有没有办法为 C# 接口创建默认属性实现
我喜欢针对接口创建扩展方法以提供默认功能的技术。它非常方便的地方之一是将一些内容放在虚拟类上以进行单元测试。
例如,
public interface IEmployee
{
IAddress Address { get; set; }
IAddress GetAddress();
void SetAddress(IAddress address);
}
public class Employee : IEmployee
{
// Complex production stuff here (causes DB access)
}
public class TestEmployee : IEmployee
{
// Simple unit testing stuff goes here (in memory only)
}
public static class EmployeeExtensions
{
public static IAddress GetAddress(this IEmployee employee)
{
// Some sort of magic (maybe using IOC)
// 'employee' can be either of type 'Employee' or of type 'TestEmployee'
}
public static void SetAddress(this IEmployee employee, IAddress address)
{
// Again with the magic
}
}
好吧,也许不是一个很好的例子,但您明白了...
关键是可以针对 Employee 和 TestEmployee 调用 GetAddress 和 SetAddress,而无需它们中任何一个的代码支持。不幸的是,这感觉更像 Java,而不是 C#。我真正想做的就是直接使用 Address 属性,并让它发挥与方法相同的作用。我想避免的是必须在具体类中编写代码来执行此操作(尤其是在 TestEmployee 中)。
有没有办法为 IEmployee 的 Address 属性提供默认实现?
我知道 C# 属性实际上是底层的方法。无论如何以某种方式为这些提供实现吗?
可以用不同的 .NET 语言来完成吗?
I like the technique of creating extension methods against interfaces to provide default functionality. One of the places it is very handy is in putting some meat on dummy classes for unit tests.
For example,
public interface IEmployee
{
IAddress Address { get; set; }
IAddress GetAddress();
void SetAddress(IAddress address);
}
public class Employee : IEmployee
{
// Complex production stuff here (causes DB access)
}
public class TestEmployee : IEmployee
{
// Simple unit testing stuff goes here (in memory only)
}
public static class EmployeeExtensions
{
public static IAddress GetAddress(this IEmployee employee)
{
// Some sort of magic (maybe using IOC)
// 'employee' can be either of type 'Employee' or of type 'TestEmployee'
}
public static void SetAddress(this IEmployee employee, IAddress address)
{
// Again with the magic
}
}
Ok, maybe not a great example but you get the idea...
The key is that GetAddress and SetAddress can be called against both Employee and TestEmployee without code support from either of them. Unfortunately, this feels a little more like Java than C#. What I would really love to do for both is to work directly with the Address property and have it do all the same magic that the methods do. What I want to avoid is having to write code in the concrete classes to do it (especially in TestEmployee).
Is there any way to provide default implementations for the Address property of IEmployee?
I know that C# properties are actually methods under the hood. Anyway of providing implementations for those somehow?
Could it be done in a different .NET language?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您已经发现的,您无法通过扩展方法添加属性。如果需要简化测试,您可以使用 Moq 之类的模拟框架来避免必须在从接口继承的每个类上实现这些属性。
As you already found out, you cannot add properties through extension methods. If it's a matter of easing the tests, you could use a mocking framework like Moq to avoid having to implement those properties on each class that inherits from the interface.
我想有很多种方法可以做到这一点。正如建议的,您可以考虑只创建一个层次结构,以便这些类型的函数由基类处理。
不过,您可能对使用 T4 模板的代码生成解决方案感兴趣(来自微软)。
There are a variety of ways to do this, I suppose. As suggested you may look at just creating a hierarchy so that these types of functions are handled by the base class.
You may, however, be interested in a code-generation solution using T4 Templates (from Microsoft).