简体   繁体   English

在C#中使用静态方法实现接口

[英]Implementing Interface with static methods in C#

Suppose I have the following ILAsm code: 假设我有以下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) { }
    }

Is it possible to define a class in C# that implements this ITest interface? 是否可以在C#中定义实现此ITest接口的类?

I can implement this interface in ILAsm: 我可以在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
        }
    }

and successfully use implemented class in C# code: 并成功使用C#代码中实现的类:

        var testImpl = new TestImpl();
        testImpl.InstMethod("I'm static!"); 

But what about implementing this interface in C#? 但是在C#中实现这个接口呢?

Surprisingly (at least to me), your IL code compiles and verifies (use PEVerify for that) fine (assuming you add some .assembly directives). 令人惊讶的是(至少对我来说),你的IL代码编译和验证(使用PEVerify)很好(假设你添加了一些.assembly指令)。

And this is backed by the CLI specification (§I.8.9.4 Interface type definition): 这得到了CLI规范的支持(§I.8.9.4接口类型定义):

[…] an interface type definition shall not provide field definitions for values of the interface type (ie, instance fields), although it can declare static fields. [...]接口类型定义不应提供接口类型值(即实例字段)的字段定义,尽管它可以声明静态字段。

[…] An interface type definition can define and implement static methods since static methods are associated with the interface type itself rather than with any value of the type. [...]接口类型定义可以定义和实现静态方法,因为静态方法与接口类型本身相关联,而不是与类型的任何值相关联。

But doing this is not CLS-compliant: 但这样做不符合CLS:

CLS Rule 19: CLS-compliant interfaces shall not define static methods, nor shall they define fields. CLS规则19:符合CLS的接口不应定义静态方法,也不应定义字段。

And you can implement the interface in C#. 您可以在C#中实现该接口。 The following code compiles and works fine: 以下代码编译并正常工作:

class Test : ITest
{
    public void InstMethod(string s)
    { }
}

But it looks like you can't access the static field or the static method from C#. 但看起来你无法从C#访问静态字段或静态方法。

This is in reply to your comment that: 这是对您的评论的回复:

I see no way to get the implemented static even via reflection: var m = new Test().GetType().GetMethods(BindingFlags.Static | BindingFlags.Public); 我认为即使通过反射也无法获得实现的静态:var m = new Test()。GetType()。GetMethods(BindingFlags.Static | BindingFlags.Public); – user2341923 - user2341923

Remember, the declaring type of the method is an interface, so you must pull the method definition from the interface type. 请记住,方法的声明类型是接口,因此必须从接口类型中提取方法定义。 so roughly, I think this should work (using some linq extensions added) 粗略地说,我认为这应该工作(使用一些linq扩展添加)

var m = new Test().GetType().GetInterfaces().Where(
        i => i.IsAssignableFrom(
        typeof ITest)).First().GetMethods(
        BindingFlags.Static | BindingFlags.Public);

This would be true of any implemented members of an interface. 对于任何已实现的接口成员都是如此。 Instance or otherwise. 实例或其他。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM