none
Why we can't implement interface method(s) statically in a class?

    General discussion

  • This regarding the interface, class and static methods.

    What I wanted to know is that why a class can't implement interface's method statically i.e. why the interface methods always have to be instance method.

    Before you start drawing any conclusion let me set some background for my problem.

    My understanding about interface is that it is a way of setting expectations for a user about what to expect from a component. How the component implements that functionality (i.e. expectation) and fulfils it is something which user need not to bother. Is that right? At least philosophically, I guess.

    I had a discussion on this topic with my friends and colleagues and some of the common replies were

    1. [Most Common]. You can't allocate memory to an interface type i.e. ICustomer cust = new ICustomer() (where Customer implements ICustomer interface) is not allowed. So cust variable has to refer to a memory location which is laid down as per the specifications of Customer class. I appreciate these kind of replies but I guess such replies assumes/accept that there is a limitation in language but this doesn't answer what the actual limitation is? I mean why the compiler writers disallowed static implementation of interface methods.

    2. Another common reply. Suppose a class implements two interfaces where both interface specify a method of same signature i.e.

    public interface ICust1
    {
     void foo();
    }

    public interface ICust2
    {
     void foo();
    }

    public class Customer : ICust1, ICust2
    {
     public void foo(){ } //Which foo is this? 1 or 2
    }


    So for Customer class the foo() will be ambiguous and allowing it to static will be sort of icing on a cake i.e. hyper-ambiguous. My reply is that in such cases a language can choose to allow explicit implemenation of ICust1 and ICust2 only. This will resolve the ambiguity. So we have the solution but disallowing on this basis is not reasonable.

    3. Some says, you can implement interface method and then call a static method from it. This is an obvious workaround but not an answer.

    Please note that Visual C++ allows defining static methods in interface definition. i.e.
    Code snippet courtesy msdn (http://msdn.microsoft.com/en-us/library/3x7c29ta(VS.80).aspx ).

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    // mcppv2_interface_class2.cpp
    // compile with: /clr
    using namespace System;

    interface struct MyInterface {
       static int i;
       static void Test() {
          Console::WriteLine(i);
       }

       static MyInterface() {
          Console::WriteLine("in MyInterface static constructor");
          i = 99;
       }
    };

    ref class MyClass : public MyInterface {};

    int main() {
       MyInterface::Test();
       MyClass::MyInterface::Test();

       MyInterface ^ mi = gcnew MyClass;
       mi->Test();
    }

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    Though this is not exactly what I am after but it looks like a good alternative. Sad to know that C# doesn't allow this even.

    So all in all I am looking for a concrete reasoning for not allowing the static implementation of  interface method(s) in a class.

    What you say?

    Ishwar

    • Edited by Ishwar Jindal Tuesday, January 27, 2009 5:31 AM misspelt few words
    Tuesday, January 27, 2009 5:27 AM

All replies

  • An interface method implementation is quite a bit more than just an instance method.  It is also a virtual method.  The C# language unfortunately hides this, you don't get to use the override keyword although virtual is accepted.  This is a hard requirement, necessary to make interfaces work.  An interface reference is a pointer to entries in the class' v-table that invoke the implementation methods.

    The problem with a static method that it can't be virtual and can't generate a v-table entry.  The C# language has much tighter constraint on language constructs compared to C++/CLI.  The snippet you posted is, arguably, nonsense.  Calling a static method through an instance pointer just doesn't make any sense.  But most of all, it fails to do what interfaces are designed to do: force the inheritor of an interface to implement the method.  This code fails to build with a linker error:

    interface struct MyInterface {
      static void Test();
    };
    ref class MyClass : MyInterface {
    public:
      static void Test() /* override */ {
      }
    };

    The linker error is "unresolved token MyInterface::Test".  Pity the poor programmer who exclaims "But I've given it a concrete implementation in MyClass!!".  This should have been a compile error of course.  Unfortunately, the C++/CLI syntax won't allow that since declarations and definitions can be in different modules.  The curse of single-pass compilation.

    Given that static methods can never be overridden, they simply don't belong in an interface declaration.  They belong in a helper class:

    public static class MyInterfaceHelpers {
      public static void Test() {}
    }

    Hans Passant.
    Tuesday, January 27, 2009 12:09 PM
    Moderator
  • Hans has it absolutely correct that from a technical perspective, interfaces require a v-table, and with no instances, you get no v-table (it's an implementation detail related to the instance header in memory currently). The runtime doesn't really do much with static members, becuase it's mostly just a direct jump instruction that the compiler figures out at compile time.

    However, technical issues aside, semantically, a static member still "belongs" to a class, and if you think of an interface (by the way, C++ doesn't really do interfaces... it's all smoke and mirrors with abstract classes in the unmanaged world) as a map of guaranteed members that will be supported by a class, then intuitively, you feel as if in purely OO terms you should be able to guarantee that a static method belongs to a class, and that an invocation message should be routable to said member. Here, C++ (unmanaged) has an advantage that the compiled code is a single monolith and the compiler knows all uses of a member ahead of time. The same isn't true for C#, whose types can be dynamically linked at runtime and used by code the compiler isn't currently aware of. This adds some complications. However, it is theoretically possible, but it would need a lot of infrastructure changes to make physically possible.

    This is actually a fairly common request, and in a completely unofficial manner, I've heard some rumblings from internal MS devs that they are informally pondering some features that could appear in some future version of the platform which would enable such scenarios. But that's not to say that it will happen. Time will tell.


    -Rob Teixeira
    Tuesday, January 27, 2009 6:32 PM
  • Thanks Hans for the technical explanation behind interface, class and v-table. I agree with you that if there are some "hard requirements" which needs interface reference to be a pointer to class's v-table then it completely rules out the expectation of interface method to be a static.

    It would be really helpful if you could throw some light on these requirements.

    Ishwar Jindal

    Wednesday, January 28, 2009 4:21 AM
  • Thanks Rob for picking the exact point I raised in my post. Technically there could be some limitation due to which we can't have interface methods as static and Hans has explained it very well but I was coming more from theoretical side.

    Let's see if this changed into reality or not. Only time will tell.

    Ishwar Jindal

    Wednesday, January 28, 2009 4:35 AM