Why shouldn't C#(or .NET) allow us to put a static/shared method inside an interface?

后端 未结 7 1856
无人及你
无人及你 2020-12-11 04:24

Why shouldn\'t C#(or .NET) allow us to put a static/shared method inside an interface?

seemingly duplicate from here. but my idea is a bit different one, I just wan

相关标签:
7条回答
  • 2020-12-11 04:51

    Check out my blog entry on static methods implemented in interfaces (sorry for the shameless self reference)

    [removed broken link http:/... ]

    dotnetjunkies site is poked by totaldevpro ... so the google cached version is the only one available

    Edit: I pasted a cached version below I found:

    [...]

    Use ILAsm to compile the following:

    .assembly extern mscorlib {
     .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         
     .ver 2:0:0:0
    }
    
     .assembly MaLio.StaticInterface{
     .hash algorithm 0x00008004
     .ver 0:1:0:0
    }
    
    .module MaLio.StaticInterface.dll
    .imagebase 0x00400000
    .file alignment 0x00001000
    .stackreserve 0x00100000
    .subsystem 0x0003      
    .corflags 0x00000001   
    
    .class interface public abstract auto ansi MaLio.IMyInterface {
    
     .method public hidebysig newslot abstract virtual instance void  DoInstanceWork() cil managed  {
     } 
    
     .method public hidebysig static void  DoStaticWork() cil managed  {
         ldstr      "Static"
         call       void [mscorlib]System.Console::WriteLine(string)
         ret
     } 
    } 
    
    .class public auto ansi beforefieldinit MaLio.MyClass extends [mscorlib]System.Object implements MaLio.IMyInterface {
    
     .method public hidebysig newslot virtual final instance void  DoInstanceWork() cil managed  {
         ldstr      "Instance"
         call       void [mscorlib]System.Console::WriteLine(string)
         ret
     } 
    
     .method public hidebysig specialname rtspecialname instance void  .ctor() cil managed {
         ldarg.0
         call       instance void [mscorlib]System.Object::.ctor()
         ret
     } 
    } 
    

    This code then can be called

    System.Type myInterface = typeof(MaLio.IMyInterface);
    // show that we really are dealing with an interface 
    if (myInterface.IsInterface) {
       System.Reflection.MethodInfo staticMethod = myInterface.GetMethod("DoStaticWork");
       staticMethod.Invoke(null, null);
    }
    

    Intellisense (VS) does not work here as expected. It recognized the static method as an instance method of the interface, and the code (if following the intellisense prompts) looks all in order as if it were going to compile. The C# compiler (MS C#) does not compile the code as C# does not suppport implemented static methods on interfaces, and can from C# only be invoked via reflection.

    I have not tested with other IDE's such as SharpDevelop ... so have no idea as yet how it would deal with this situation.

    0 讨论(0)
  • 2020-12-11 04:52

    For your purpose, it will be much better to decouple plugin interface from plugin loader implementation: this will make your design much less coupled and more cohesive (thus reducing complexity).

    As for "static methods in interface", see this.

    And as a sidenote: you don't really want to invent yet another plugin architecture: take a look at MEF.

    0 讨论(0)
  • 2020-12-11 04:52

    An interface is just that, an interface. It isn't meant to be used to describe behavior. When a class implements an interface, the class just says "I promise that I provide methods/events/etc with these signatures".

    What you want is an interface without the static method and an abstract base class that implements the interface and the static method. Then other classes can inherit from the base class and change the interface's method implementations. But even this is a questionable design.

    0 讨论(0)
  • 2020-12-11 04:59

    I've run into this several times and did some research. The sad part is, IL actually supports this. I got so frustrated with this I wrote a blog post about it. You can find it here.

    0 讨论(0)
  • 2020-12-11 05:02

    static methods are associated with the type in which they are declared and not relevant for overriding. If you were able to attach a static method to an interface, you would have to reference it via the interface itself, e.g. ITaskPlugin.GetPlugins(...)

    What you want to do is either:

    1) Put your method in an abstract base class, as interfaces are not designed to hold implementation code, or

    2) Create an extension method which applies to the interface and then you'll have access to it without having to use a base class.

    0 讨论(0)
  • 2020-12-11 05:14

    The idea of an interface is to represent a contract, not implementation.

    I can't remember offhand whether IL actually does allow static methods with implementations in interfaces - I've a sneaky suspicion that it does - but that muddies the concept somewhat.

    I can see your point - it's sometimes useful to know what helper methods are available which are connected with an interface (and extension methods are particularly relevant there) but I would personally want to put those in a separate class anyway, just to keep the mental model clean.

    0 讨论(0)
提交回复
热议问题