【问题标题】:Using reflection to check if a partial method has been implemented使用反射检查是否已实现部分方法
【发布时间】:2013-11-13 13:12:45
【问题描述】:

背景

我正在使用 Linq to SQL,因此生成的 DBML 文件包含自动生成的类。生成过程的一部分为某些操作创建部分方法,在我的例子中,我感兴趣的两种方法与表记录的插入和更新有关。这些部分方法是根据 DBML 设计器中创建的每个表生成的,例如:

partial void InsertMyTable(MyTable instance);
partial void UpdateMyTable(MyTable instance);

现在,我的应用程序设计的一部分要求始终为每个表实现这两个部分方法。 (它们本质上用于为正在插入/更新的记录添加时间戳)。

要求

我有一个单元测试项目,虽然这可能不是常见的做法,但我想包括一些测试,以确保某些事情已正确实施。在这种情况下,我想确保开发人员记得实现上面提到的部分方法(我不关心实际的实现,只关心它们已经实现了)。

问题

我需要做的是使用反射来检查每个部分方法是否已实现,但我无法确定如何确定。

尝试的努力

到目前为止,我已经设法获得了包含在数据上下文中的方法列表,并且我能够将其与每个表的预期方法进行比较。问题是我找不到方法来确定给定的部分方法是否真的有实现:

var methods = (typeof(MyDataContext)).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var method in methods) 
{
    Console.WriteLine(method.Name);
    //how to check if method is implemented, or just an unimplemented partial
}

【问题讨论】:

  • 提供throw new NotImplementedException()的默认实现不是更容易吗?
  • @James:partial 方法是自动生成的,这意味着开发人员需要记住每次向 DBML 设计器添加新表时都要实现它
  • 或者创建一个属性,将其附加到已实现的方法上,看看它是否存在于您的检查中。
  • 部分方法对我来说是新的,但似乎在运行时,如果它没有被实现,它不会在 GetMethods 调用中返回,因为编译器根据@987654321丢弃未实现的部分@
  • BindingFlags.DeclaredOnly 应该忽略继承的成员

标签: c# reflection partial-methods


【解决方案1】:

你已经工作了。如果partial 方法没有实现,那么它根本不存在。没有您可能通过反射偶然发现的“声明存根”。部分方法有一个实现,或者它被编译器完全删除。

所以基本上:如果您找不到使用 GetMethod / GetMethods 的方法(根据问题,使用适当的 BindingFlags) - 那么它没有实现。

【讨论】:

  • 是的,你是对的,我没有注意到我的列表没有包含那些未实现的!所以解决方法就是检查该方法是否存在
【解决方案2】:

作为另一种想法(在编译时很明显,并且不易受到混淆问题的影响):

// generated code
public partial class Whatever : ISomeInterface<MyTable>
{
    //...
}

//somewhere else
public interface ISomeInterface<T>
{
    void Insert(T instance);
    void Update(T instance);
}

现在编译器不会让用户在没有完全实现这个接口的情况下继续进行,大概是在一个部分类中:

partial class Whatever
{
    public void Insert(MyTable instance) {...}
    public void Update(MyTable instance) {...}
}

(注意他们仍然可以使用显式接口实现,但您应该在访问数据时自己使用该接口;避免更多反射)

【讨论】:

  • 我明白你在这里的意思,但是它对我的情况没有帮助,因为课程是自动生成的
  • @musefan 如果是您自动生成它们,那应该不是问题;如果它不是你,那么:确实
【解决方案3】:

当我遇到同样的问题时,我解决了如下:

var Method = (typeof(Entities))
.GetMethods(System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.FirstOrDefault(x => x.Name == "SomeMethodShouldBeOnPartialClass");
if (Method != null) Method.Invoke(this,null);

【讨论】:

    猜你喜欢
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 2021-08-11
    • 2010-12-03
    相关资源
    最近更新 更多