Implementing an interface with static methods in C #

Suppose I have the following ILAsm code:

.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?

I can implement this interface in 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 the implemented class in C # code:

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

But what about implementing this interface in C #?

+7
c # clr il
source share
2 answers

Surprisingly (at least for me), your IL code compiles and checks (use PEVerify for this) in order (if you add some .assembly directives).

And this is confirmed by the CLI specification (Β§I.8.9.4 Interface type definition):

[...] an interface type definition should not contain field definitions for interface type values ​​(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, and not with any type value.

But this does not match the CLS:

CLS Rule 19: Interfaces compatible with CLS must not define static methods and must not define fields.

And you can implement the interface in C #. The following code compiles and works fine:

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

But it looks like you cannot access a static field or static method from C #.

+6
source share

In response to your comment, that:

I do not see the possibility of getting an implemented static object even through reflection: var m = new Test (). GetType (). GetMethods (BindingFlags.Static | BindingFlags.Public); - user2341923

Remember that a method declaration type is an interface, so you must infer the method definition from the interface type. so rude, I think this should work (using some linq extensions)

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

This will be true for any implemented interface elements. Instance or otherwise.

+1
source share

All Articles