5

背景

我正在使用 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
}
4

3 回答 3

11

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

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

于 2013-11-13T13:18:53.300 回答
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) {...}
}

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

于 2013-11-13T13:26:40.267 回答
0

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

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);
于 2015-06-23T07:23:15.993 回答