C# 使用反射检查是否已实现分部方法

C# 使用反射检查是否已实现分部方法,c#,reflection,partial-methods,C#,Reflection,Partial Methods,背景 我使用LINQtoSQL,因此生成了一个包含自动生成类的DBML文件。生成过程的一部分为某些操作创建部分方法,在我的例子中,我感兴趣的两个方法与表记录的插入和更新相关。这些分部方法是根据在DBML设计器中创建的每个表生成的,例如: partial void InsertMyTable(MyTable instance); partial void UpdateMyTable(MyTable instance); 现在,我的应用程序设计的一部分要求这两个分部方法总是对每个表实现。(它们基本

背景

我使用LINQtoSQL,因此生成了一个包含自动生成类的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
}

你已经做过的工作。如果
partial
方法没有实现,那么它根本不存在。不存在通过反射意外找到的“声明存根”。分部方法有一个实现,或者它被编译器完全删除

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

作为一种替代方案(在编译时很明显,并且不容易出现混淆问题):


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

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

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);

提供
throw new NotImplementedException()的默认实现不是更容易吗?@James:partial方法是自动生成的,这意味着开发人员需要记住在每次向DBML设计器中添加新表时都要实现它,或者创建一个附加到已实现方法上的属性,并查看它是否存在于您的检查中。部分方法对我来说是新的,但似乎在运行时,如果尚未实现,它不会在GetMethods调用中返回,因为编译器根据BindingFlags丢弃未实现的部分。DeclaredOnly应该忽略继承的成员。您是对的,我没有注意到我的列表中没有包含未实现的成员!所以解决方法就是检查这个方法在allI是否存在,我明白你在这里的意思,但是在我的情况下,它没有帮助,因为这个类是自动的-generated@musefan如果是您自动生成它们,那么这不应该是一个问题;如果不是你,那么:真的
partial class Whatever
{
    public void Insert(MyTable instance) {...}
    public void Update(MyTable instance) {...}
}
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);