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

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

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.

static method cannot implement interface method, why?

See this thread from JoelOnSoftware describing the reasons behind this.

Basically the interface is the contract between the consumer and the provider, and a static method belongs to the class, and not each instance of the class as such.

An earlier question on SO also deal with the exact same question:
Why Doesn't C# Allow Static Methods to Implement an Interface?

How can I implement static methods on an interface?

You can't define static members on an interface in C#. An interface is a contract for instances.

I would recommend creating the interface as you are currently, but without the static keyword. Then create a class StaticIInterface that implements the interface and calls the static C++ methods. To do unit testing, create another class FakeIInterface, that also implements the interface, but does what you need to handle your unit tests.

Once you have these 2 classes defined, you can create the one you need for your environment, and pass it to MyClass's constructor.

Why can't interfaces specify static methods?

Suppose you could specify in an interface that a type had to have a particular static method... how would you call it? Polymorphism works through instances - whereas static members explicitly don't use instances.

Now, having said that, there's one situation in which I can see static interface members working: generic types. For example:

// This isn't valid code...
public void Foo<T>() where T : ICodeGenerator
{
string type = T.GetDbConnectionType();
}

That would call the static member on the concrete type T.

I've blogged more about this, but I suspect the benefit doesn't justify the complexity.

In terms of alternatives - usually you'd have another interface, and have separate types to implement that interface. That works well in some contexts, but not in others.

Can static methods implement an interface in .NET

Short answer: No.

Longer answer:

This concept doesn't really make any sense. The point of an interface is to define a base type that describes a contract for various implementations. I can declare a variable using a static type of IFoo, which tells the compiler I don't know what type this will be at runtime, but I assure you it will have a certain set of methods. - Thus, the compiler will let you call those methods, which will be resolved at runtime.

A static method is always bound to one and only one class, so there's no instance to refer to.

Alternative to static methods for interface

From logical point of view these methods should be static, because they logically don't work on a particular instance and don't use shared resources.This class don't have a state as well. But... from a pragmatic point of view, instant class brings many benefits, like:

  • class (interface) if fully testable,
  • follows the OOP and SOLID principles,
  • can be registered as singleton, so you can create only one instance of this object,
  • it's easy to add any dependencies to these classes
  • easy to maintain
  • some useful design patterns can be applied (e.g. decorator, composite)
  • can be lazy loaded and disposed in any time

In your case, in my opinion, you should hide this implementation behind the interface and register it as a singleton, e.g.(using autofac)

builder.RegisterType<MyXmlSerializer>().As<IDataSerializer>().SingleInstance();

In addition, if you need to, you can create an extension method for this interface and add static methods to this contract.

More information can be found here:

  • Instance methods vs static

  • Static class vs singleton

  • Extension methods

Implementing Interface with static methods in C#

Surprisingly (at least to me), your IL code compiles and verifies (use PEVerify for that) fine (assuming you add some .assembly directives).

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

[…] an interface type definition shall not provide field definitions for values of the interface type (i.e., 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 Rule 19: CLS-compliant interfaces shall not define static methods, nor shall they 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 can't access the static field or the static method from C#.



Related Topics



Leave a reply



Submit