>假设我有以下ILAsm代码:
.class public interface abstract ITest
{
.field public static int32 counter
.method public static void StaticMethod(string str)
{
ldarg.0
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public virtual abstract void InstMethod(string) { }
}
是否可以在 C# 中定义一个实现此ITest
接口的类?
我可以在 ILAsm中实现此接口:
.class public TestImpl extends [mscorlib]System.Object implements ITest
{
.method public virtual void InstMethod(string str)
{
ldarg.1
call void ITest::StaticMethod(string)
ret
}
.method public specialname rtspecialname instance void .ctor()
{
ldarg.0
call instance void .base::.ctor()
ret
}
}
并在 C# 代码中成功使用实现的类:
var testImpl = new TestImpl();
testImpl.InstMethod("I'm static!");
但是在 C# 中实现此接口呢?
令人惊讶的是(至少对我来说),您的 IL 代码编译和验证(为此使用 PEVerify)很好(假设您添加了一些.assembly
指令)。
这得到了 CLI 规范(§I.8.9.4 接口类型定义)的支持:
[...]接口类型定义不应为接口类型的值(即实例字段)提供字段定义,尽管它可以声明静态字段。
[...]接口类型定义可以定义和实现静态方法,因为静态 方法与接口类型本身相关联,而不是与类型的任何值相关联。
但这样做不符合 CLS:
CLS 规则 19:符合 CLS 的接口不得定义静态方法,也不得定义字段。
您可以在 C# 中实现该接口。以下代码可编译并正常工作:
class Test : ITest
{
public void InstMethod(string s)
{ }
}
但看起来您无法从 C# 访问静态字段或静态方法。
这是对您的评论的回复:
请记住,方法我认为即使通过反射也无法获得实现的静态:var m = 新测试()。GetType()。GetMethods(BindingFlags.Static |BindingFlags.Public);– 用户2341923
的声明类型是接口,因此必须从接口类型中提取方法定义。 所以粗略地说,我认为这应该有效(使用添加的一些 linq 扩展)
var m = new Test().GetType().GetInterfaces().Where(
i => i.IsAssignableFrom(
typeof ITest)).First().GetMethods(
BindingFlags.Static | BindingFlags.Public);
接口的任何已实现成员都是如此。实例或其他。