Why Doesn't C# Allow Static Methods to Implement an Interface?

Why was C# designed this way?

As I understand it, an interface only describes behaviour, and serves the purpose of describing a contractual obligation for classes implementing the interface that certain behaviour is implemented.

If classes wish to implement that behavour in a shared method, why shouldn't they?

Here is an example of what I have in mind:

// These items will be displayed in a list on the screen.
public interface IListItem {
  string ScreenName();
  ...
}

public class Animal: IListItem {
    // All animals will be called "Animal".
    public static string ScreenName() {
        return "Animal";
    }
....
}

public class Person: IListItem {

    private string name;

    // All persons will be called by their individual names.
    public string ScreenName() {
        return name;
    }

    ....

 }

Solution 1:

Assuming you are asking why you can't do this:

public interface IFoo {
    void Bar();
}

public class Foo: IFoo {
    public static void Bar() {}
}

This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface.


To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.
public class Animal: IListItem {
    /* Can be tough to come up with a different, yet meaningful name!
     * A different casing convention, like Java has, would help here.
     */
    public const string AnimalScreenName = "Animal";
    public string ScreenName(){ return AnimalScreenName; }
}

For a more complicated situation, you could always declare another static method and delegate to that. In trying come up with an example, I couldn't think of any reason you would do something non-trivial in both a static and instance context, so I'll spare you a FooBar blob, and take it as an indication that it might not be a good idea.

Solution 2:

My (simplified) technical reason is that static methods are not in the vtable, and the call site is chosen at compile time. It's the same reason you can't have override or virtual static members. For more details, you'd need a CS grad or compiler wonk - of which I'm neither.

For the political reason, I'll quote Eric Lippert (who is a compiler wonk, and holds a Bachelor of Mathematics, Computer science and Applied Mathematics from University of Waterloo (source: LinkedIn):

...the core design principle of static methods, the principle that gives them their name...[is]...it can always be determined exactly, at compile time, what method will be called. That is, the method can be resolved solely by static analysis of the code.

Note that Lippert does leave room for a so-called type method:

That is, a method associated with a type (like a static), which does not take a non-nullable “this” argument (unlike an instance or virtual), but one where the method called would depend on the constructed type of T (unlike a static, which must be determinable at compile time).

but is yet to be convinced of its usefulness.

Solution 3:

Most answers here seem to miss the whole point. Polymorphism can be used not only between instances, but also between types. This is often needed, when we use generics.

Suppose we have type parameter in generic method and we need to do some operation with it. We dont want to instantinate, because we are unaware of the constructors.

For example:

Repository GetRepository<T>()
{
  //need to call T.IsQueryable, but can't!!!
  //need to call T.RowCount
  //need to call T.DoSomeStaticMath(int param)
}

...
var r = GetRepository<Customer>()

Unfortunately, I can come up only with "ugly" alternatives:

  • Use reflection Ugly and beats the idea of interfaces and polymorphism.

  • Create completely separate factory class

    This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class.

  • Instantiate and then call the desired interface method

    This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.

Example:

public class Customer 
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  void SomeOtherMethod() 
  { 
    //do work...
  }
}

in order to use instantination for solving the static interface problem we need to do the following thing:

public class Customer: IDoSomeStaticMath
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  //dummy instance
  public Customer() { IsDummy = true; }

  int DoSomeStaticMath(int a) { }

  void SomeOtherMethod() 
  { 
    if(!IsDummy) 
    {
      //do work...
    }
  }
}

This is obviously ugly and also unnecessary complicates the code for all other methods. Obviously, not an elegant solution either!

Solution 4:

I know it's an old question, but it's interesting. The example isn't the best. I think it would be much clearer if you showed a usage case:

string DoSomething<T>() where T:ISomeFunction
{
  if (T.someFunction())
    ...
}

Merely being able to have static methods implement an interface would not achieve what you want; what would be needed would be to have static members as part of an interface. I can certainly imagine many usage cases for that, especially when it comes to being able to create things. Two approaches I could offer which might be helpful:

  1. Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default().
  2. For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.

None of these approaches is really appealing. On the other hand, I would expect that if the mechanisms existed in CLR to provide this sort of functionality cleanly, .net would allow one to specify parameterized "new" constraints (since knowing if a class has a constructor with a particular signature would seem to be comparable in difficulty to knowing if it has a static method with a particular signature).