在接口中包含扩展方法
本文关键字:扩展 方法 包含 接口 | 更新日期: 2023-09-27 18:03:48
当从一个具体类中抽象出一个接口时,该接口是否应该包含扩展方法?
就像你描述的那样,我会说不。如果您的扩展方法显然只在单元测试的上下文中有用,那么将它们作为测试项目中的扩展方法保留。
另一种方法是将扩展方法移到类中(将它们更改为普通的公共方法),并将它们包含在接口中。这将使它们对所有使用您的类的东西都可用,这对于单元测试代码来说是不可取的。
扩展方法对于向你无法控制的类添加功能或分离责任区域非常有用。
如果一个类依赖于SomeOtherClass
,并且它同时依赖于SomeOtherClass
的实例成员和静态成员,那么您可以
- 将静态成员更改为可以成为接口一部分的实例成员
- 将静态成员放在单独的扩展类(或其他依赖)中,以便
SomeOtherClass
可以替换为接口。
通过同时使用依赖的实例成员和静态成员,它有效地将两个依赖合二为一。您取决于对象(实例成员)和对象的类型(静态成员)
如果类本身需要这些方法才能发挥作用,那么它们应该是该类的成员。如果它们是为了让其他类以该类职责之外的方式使用该类而需要的(比如将一个类映射到另一个类的方法),那么我会将其分离出来。
如果方法是类和其他类都需要的,那么你可以把它分离成另一个类,原类和其他类都可以依赖。
举例来说,对于以下两个类:
class SomeClass
{
public Prop1 { get; }
public void Method1() { .... }
}
static class SomeExtensions
{
public static ExtensionMethod(SomeClass this sc) { ... }
}
正如其他人所说,在创建接口时,您只能使用SomeClass
中的公共非静态成员,但是,也值得修改扩展方法以引用接口,而不是同时引用具体类型:
static class SomeExtensions
{
public static ExtensionMethod(ISomeClass this sc) { ... }
}
No。你在这方面有一些问题。首先,接口只描述公共实例方法的签名(也就是说,它们可能没有实现,你也不能在接口中指定静态方法)。扩展方法在编译时必须有一个实现,它们不是实例方法,而是静态方法。此时请注意,根据文档
在您的代码中,您使用实例方法调用扩展方法语法。但是,中间语言(IL)由编译器将您的代码转换为对静态方法的调用。
换句话说,它不是真正的实例方法(即使你可以把它当作实例方法);在底层,它仍然是一个静态方法。
另外,扩展方法必须在静态类中定义(参见Microsoft关于如何实现扩展方法的说明)。
注意可以在接口上有一个扩展方法;并不要求你要扩展的类型必须是具体的。例如:
public static class Class2
{
public static void Extension(this ITestInterface test)
{
Console.Out.WriteLine("This is allowed");
}
}
现在,当我实例化一个实现ITestInterface接口的具体类时,我可以在它上面调用扩展方法:
// "Test" is some class that implements the ITestInterface interface
ITestInterface useExtensionMethod = new Test();
useExtensionMethod.Extension();