458

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;
    }

    ....

 }
Otiel
  • 17,292
  • 13
  • 70
  • 120
Kramii
  • 8,098
  • 4
  • 28
  • 36
  • 6
    Well, Java 8 has it (http://stackoverflow.com/questions/23148471/static-methods-in-java-interface). – liang Jul 11 '15 at 04:12
  • 1
    See how you can combine a static behavior with inheritance or interface implementation: http://stackoverflow.com/a/13567309/880990 – Olivier Jacot-Descombes Jul 30 '16 at 14:19
  • 1
    `IListItem.ScreenName() => ScreenName()` (using C# 7 syntax) will implement the interface method explicitly by calling the static method. Things get ugly when you add inheritance to that, though (you have to reimplement the interface) – Jeroen Mostert Apr 18 '17 at 14:34
  • 2
    Just letting everyone know that the wait is now over! C# 8.0 has static interface methods: https://dotnetfiddle.net/Lrzy6y (although they work a little different to how OP wanted them to work - you don't have to implement them) – Jamie Twells Nov 21 '19 at 20:08

25 Answers25

224

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.

Chris Marasti-Georg
  • 32,594
  • 15
  • 88
  • 130
  • 7
    A perfect example! But I'm not sure I understand your reasoning. Surely the compiler *could* have been designed to look at the statuc members as well? Don't the instances have a table of addresses for the implementation of theis methods? Couldn't the static methods be included in this table? – Kramii Nov 03 '08 at 16:03
  • I realized as I was going through to clarify that what you ask for could certainly be implemented by the compiler. So, I changed my response to better answer "Why?" – Chris Marasti-Georg Nov 03 '08 at 16:05
  • 12
    There is a case where this could be useful. For instance, I want all the implementors to implement a GetInstance method that takes an XElement argument. I can neither define that as a static method in the interface, nor demand a constructor signature from the interface. – oleks Feb 16 '11 at 13:23
  • 1
    If you have an instance of the class, you can have a non-static method that does what you're specifying. If you don't have an instance... how do you know which implementation to use? – Chris Marasti-Georg Feb 22 '11 at 17:10
  • 25
    A lot of folks have weighed in on both sides: from "This makes no sense" to "It's a bug, I wish you could." (I think there are valid use cases for it, which is how I ended up here.) As a workaround, the instance method can simply delegate to a static method. – harpo Mar 31 '11 at 18:27
  • 5
    You could also simply implement the piece as an extension method onto the base interface, as in: `public static object MethodName(this IBaseClass base)` within a static class. The downside, however, is that unlike an interface inheritance - this does not force / allow the individual inheritors to override the methodology well. – Troy Alford Nov 03 '12 at 00:26
  • 8
    It would make a lot of sense with generics. For example void Something() where T : ISomeInterface { new T().DoSomething1(); T.DoSomething2(); } – Francisco Ryan Tolmasky I Dec 18 '13 at 10:06
  • 1
    Hi. I arrive two years later, to ask about this: "Methods specified on an interface should be there to specify the contract for interacting with an object." Why is that? Why only interacting with an object? If this is true, C#'s reasoning is great, but why is this true? – Blueriver Oct 29 '15 at 07:34
  • @harpo: What would be helpful would be if .NET could allow existing interfaces to be extended with new members, with the system auto-generating for any missing implementation member a simple "default" method that chains to one of two suitably named and tagged static method within the interface (if they exist), with an "extra" first parameter of type `T` for class implementations, or `ref T` for struct implementations. The efficiency of some interfaces like `IEnumerable` could be greatly enhanced by adding members like `int Move(int)` to move more than one element at a time. – supercat Sep 01 '16 at 19:29
  • @supercat are you describing extension methods? – Chris Marasti-Georg Sep 13 '16 at 20:42
  • @ChrisMarasti-Georg: Extention methods are compile-time syntactic sugar; something like `SomeEnumerable.Count()` gets turned into `Enumerator.Count(SomeIEnumerable)` if the compiler is aware of the latter extension method. What I'm describing would allow something like `bool Move(ref int)` to be added as an actual member of `IEnumerable`, with the *.NET runtime* using attributes attached to that interface to auto-generate an implementation like `bool Move(ref int n) { return IEnumerable.Move(this, ref n); };`. Classes which can support move-by-N quickly (as `List.Enumerator`... – supercat Sep 13 '16 at 20:54
  • ...likely would) could process an N-element move in a single step, but those which aren't programmed for that ability could be handled by the static method that would simply call `MoveNext` an appropriate number of times. Note that if one used `Append` to join a passed a 1,000,000-element `List` with a 12-item iterator, an attempt to skip ahead 1,000,0005 items could be handled efficiently by creating a the `List` enumerator, asking it to move 1,000,005 steps, finding out that it fell 5 items short, and then asking the iterator to advance 5 items. Much better than having to call... – supercat Sep 13 '16 at 20:58
  • ...`MoveNext` on the `List.Enumerator` 1,000,000 times. – supercat Sep 13 '16 at 20:58
  • @Blueriver I am wondering the exact same thing. And I'm not sure Chris' reasoning in this answer is quite right. The way I see it, interfaces define a communicating contract on a 'type', not individual objects, so given that, there's absolutely no reason whatsoever on this planet in this universe why it shouldn't be possible to implement a property/method as static. Unfortunately you can't in C#, or at least not easily as others have shown. Took me a long time but think I've finally got around to finding what I consider to be a flaw with C#. – Ash Nov 24 '17 at 00:07
  • @Ash I understand that a lot of smarter-than-me people have said how this is technically feasible and just not in C# and such, but... Is there really any use case aside from "One of these methods that I've implemented/overridden from a base class/interface, I'd like to also expose in a static context by the same name"? This is a minor inconvenience in some cases (give the static method a different name and delegate the non-static version to it) and ok, a flaw. What other use case is there? Also, I do think Mark's answer should be the accepted one, not mine. – Chris Marasti-Georg Nov 28 '17 at 18:39
  • @Chris For my particular use-case, it means I have to use a singleton...but that's assuming the consumer does indeed make use of the singleton instance; there's no restricting tremendous amounts of instances being created, one for each time a particular functionality is needed, which just happens to be the same across all instances, but we can't enforce static in the contract so... – Ash Dec 06 '17 at 06:17
  • @Ash a properly implemented singleton pattern won't allow multiple instances to be created. I'd use dependency injection and manage object lifecycle through the container though. – Chris Marasti-Georg Dec 06 '17 at 16:26
  • I can't agree that wanting a static method on an interface is inherently bad design. – Mashmagar Feb 14 '19 at 13:25
177

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.

Dan Jagnow
  • 843
  • 9
  • 22
Mark Brackett
  • 81,638
  • 17
  • 102
  • 150
  • 5
    Excellent, this is the answer that I wanted to write - I just didn't know the implementation detail. – Chris Marasti-Georg Nov 03 '08 at 17:44
  • 5
    Great answer. And I want this 'type method'! Would be useful in so many occasions (think about metadata for a type/class). – Philip Daubmeier Apr 18 '12 at 14:22
  • 25
    This is the correct answer. You pass an interface to someone, they need to know how to call a method. An interface is just a *virtual method table*. Your static class doesn't have that. The caller wouldn't know *how* to call a method. (Before i read this answer i thought C# was just being pedantic. Now i realize it's a technical limitation, imposed by *what an interface **is***). Other people will talk down to you about how it's a bad design. It's not a bad design - it's a technical limitation. – Ian Boyd Jun 11 '12 at 17:18
  • In C# - couldn't this be implemented as: `public static object Method(this T t)`? Or am I forgetting that there is a specific C# restriction against this kind of extension method? – Troy Alford Nov 03 '12 at 00:28
  • 2
    +1 for actually answering the question and not being pedantic and snotty. Like Ian Boyd said: "It's not a bad design - it's a technical limitation." – Joshua Pech Mar 30 '13 at 15:23
  • Just as a theoretical thought play: Why can't the compiler implicitly generate a class (with a vtable!) for each type that statically implements an interface, have the methods of that class forward all calls to the static methods, and insert an instance of that class whenever the type is casted to the interface type (e.g. assigned to a variable of that interface type)? – O. R. Mapper Jan 29 '14 at 21:10
  • Also, I am not sure I see a full reasoning in the first quotation: When the methods are called "as static methods" (class.method), the method *is* still resolved solely by static analysis of the code. Isn't this topic rather about what is called when *interface* methods are invoked, which is usually *not* exactly known at compile-time, anyway? – O. R. Mapper Jan 29 '14 at 21:12
  • 3
    It's totally possible to generate an object for a static class with associated vtable. Look at how Scala handles `object`s and how they are permitted to implement interfaces. – Sebastian Graf May 08 '14 at 19:45
  • @Sebastian - I'm getting dangerously close to eclipsing my compiler knowledge, but as C# uses the term (consistent with other C-based languages) the *definition* of a static method is statically dispatched. That precludes a vtable (which would be dynamically dispatched). Scala's objects aren't actually static - they're really just a normal class implemented as a singleton (with a vtable and it's associated pros and cons). – Mark Brackett May 09 '14 at 13:22
  • 3
    A vtable could just point to the static implementation, much like `Func<>` does, but instead of just containing one pointer, it contains all pointers for methods required by the interface. Using `static` like in static dispatch does artificially hamstring the language for the sake of 'object-orientation'. – Sebastian Graf May 09 '14 at 21:13
  • 2
    Most object-oriented languages tend to be too strict wrt dispatch: If the runtime type of an object is known, then it makes absolutely no sense to fetch the actual method through a vtable access (would make for a cheap compiler optimization). On the other hand, saying that a statically dispatched method (either `static` or just non-`virtual`) can't satisfy an interface is evenly brainless, because for satisfying an interface all that is needed is a vtable for the mapping to implementing methods. That's where all C-like OO languages go wrong. Easy to say in retrospect, I guess. /rant – Sebastian Graf May 09 '14 at 21:22
  • 2
    tldr; static vs. dynamic dispatch shouldn't depend on the declaration of a method but on the usage, as done in Go, Rust and Haskell's type classes. – Sebastian Graf May 09 '14 at 21:26
  • with polymorphic instantiation, it should be possible to define a static type contract of a parametric type-paramater, and then call those static methods. – David Jeske Oct 24 '14 at 05:32
  • @IanBoyd I think the 'bad design' here is is what has *caused* the technical limitation. In other words, if the framework were designed differently this technical limitation wouldn't exist. – DCShannon Dec 30 '14 at 04:03
  • 1
    What I want is a way to give a promise that a class will have a constant such as "Zero" or "NaN". To get this, I would need static members in interfaces, and also a way to refer to the implementing type within the interface, which does not exist either. – William Jockusch Mar 19 '15 at 15:23
  • 1
    All this bad design/technical limitation talk is kind of missing the point...which is that, evidently, *your* definition of "static" doesn't match the C# compiler team's definition of "static". It's obviously possible to create the thing that you're asking for (as Lippert points out and as others have pointed out in various languages) - but we wouldn't call them "static" methods unless we have the C# compiler team change their definition. – Mark Brackett Mar 19 '15 at 17:17
  • 1
    The obvious use case is decoupling from the concrete class to support DI and testing of the "static" implementation. I think the "type method" case you're talking about will meet this need just nicely if it were to be implemented in C#. I imagine that in most cases, devs are not that concerned with the inner-workings of the vtable or deterministic method resolution (nor should they be in most cases) but have a higher-order need - or at least, imagine they do. Either way, your +1 from me is, for the most part, for introducing the term "compiler wonk". – Richard Hauer Aug 07 '16 at 05:33
  • @MarkBrackett "static" is defined by the C# spec. Adding static methods to interfaces wouldn't produce any conflict with the spec. – Mashmagar Feb 14 '19 at 13:22
  • @Mashmagar - well, if you changed the spec it wouldn't conflict....but that's pretty much a tautology and echoes what I already said. Such a thing is obviously *possible* and could be named whatever those-in-charge-of-naming-things want. As of yet, those-in-charge-of-adding-things however, don't consider that within the definition of "static" nor a useful enough feature to add under a different name. Generally, that's always going to be the (possibly not very satisfying) answer to those things which are possible, but not yet implemented.... – Mark Brackett Feb 19 '19 at 14:51
99

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!

Community
  • 1
  • 1
  • 35
    +1 for "Most answers here seem to miss the whole point."; it's incredible how it seems that pretty much all the answers dodge the core of the question to delve into mostly unuseful verbiage... –  May 31 '12 at 16:06
  • Your examples don't make sense to me... the "IsQueryable" functionality can be an annotation/attribute, or better yet, an interface that the class implements (otherwise, how do you query it?). RowCount... of what? The number of customers? That's something the customer repository should do, not the customer class. The static math example is incomplete, so I'm not sure what you would actually be trying to do there. – Chris Marasti-Georg Oct 23 '12 at 14:54
  • 5
    @Chris Here's a specific example that made me just hit this restriction again. I want to add an IResettable interface to classes to indicate that they cache certain data in static variables that can be reset by the site admin (e.g. an order category list, a set of vat rates, a list of categories retrieved from an external API) to reduce the DB and external API hits, this would obviously use a static method reset. This allows me to just automate the detection of which classes can be reset. I can still do this, but the method is not enforced or automatically added in the IDE and relies on hope. – mattmanser Oct 26 '12 at 14:18
  • @mattmanser I'd say you've reached the point in your architecture where you need to use an actual cache, rather than static variables on domain objects (a decision which I would also question, but that's a different discussion :)). – Chris Marasti-Georg Oct 26 '12 at 19:00
  • 7
    @Chris I disagree, massive overkill. It's always a sign of a language flaw when more architecture is the 'best' solution. Remember all the patterns no-one talks about any more since C# got generics and anonymous methods? – mattmanser Oct 30 '12 at 09:15
  • 3
    Can't you use "where T : IQueryable, T : IDoSomeStaticMath" or similar ? – Roger Willcocks Dec 07 '12 at 02:44
  • 1
    @ChrisMarasti-Georg: A classic example is typed database classes which all have a retrieve-by-key. `Customer cust = Customer.Retrieve(233);`. These database classes often inherit one "database class" type, and often share properties, but you can't ever define/call their Retrieve function(s) as general thing because it is static, despite the fact they all have it. – Nyerguds May 06 '15 at 10:03
  • @Nyerguds True, that would be a decent use case. You could have something like `T Retrieve(long id)` on your `BaseDbClass`, which is still pretty intuitive I think. – Chris Marasti-Georg May 06 '15 at 13:47
  • 2
    @ChrisMarasti-Georg: A somewhat dirty but interesting way around it is this little construction: `public abstract class DBObject where T : DBObject, new()`, and then make all DB classes inherit as `DBObject`. Then you can make the retrieve-by-key a static function with return type T in the abstract superclass, make that function create a new object of T, and then call a protected `String GetRetrieveByKeyQuery()` (defined as abstract on the superclass) on that object to get the actual query to execute. Though this might be getting a tad off topic – Nyerguds May 12 '15 at 13:26
  • @Nyerguds it might work, but it's an ugly hack `create an instance using reflection (new() constraint does) and fill with method`. `Create an instance` is not equal to `create an empty dummy instance and then fill it` – Alex Zhukovskiy Dec 29 '15 at 14:41
  • @AlexZhukovskiy: I think you misunderstand the construction. It does not _involve_ any dummy objects. I have a superclass with static methods that return a generic type. The subclass hardcodes _itself_ to _be_ that type, so when called on the subclass, these static methods can create objects of that type and return them, as that type. – Nyerguds Jan 12 '16 at 13:09
  • @Nyerguds I think there should be any possibility to allow interfaces to have static methods so the type that inherits this interface should have spesific static method. It could be useful for any methods such as `T Parse(string source);` – Alex Zhukovskiy Jan 13 '16 at 10:20
  • @AlexZhukovskiy As I showed, it works with abstract functions with generics. But interfaces are designed to allow functions to handle _objects_ of different types on the basis of their common properties and functions. C# doesn't support handling actual types in the same way as object instances. Any stuff done like that on classes-level would probably be a mess of reflection code. – Nyerguds Jan 13 '16 at 12:55
  • @Nyerguds now it's true, but this is why i'm saying that. If this feature was included in CIL specifications when it was developed, it could me much easier. Compiler should just require specific class to have some method. We can always create instance of an object and call interface `Parse` method, but it's not the same as create it from a static method because class could have readonly fields that only can be initialized in creation time. – Alex Zhukovskiy Jan 14 '16 at 10:26
20

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

supercat
  • 69,493
  • 7
  • 143
  • 184
16

Short-sightedness, I'd guess.

When originally designed, interfaces were intended only to be used with instances of class

IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();

It was only with the introduction of interfaces as constraints for generics did adding a static method to an interface have a practical use.

(responding to comment:) I believe changing it now would require a change to the CLR, which would lead to incompatibilities with existing assemblies.

James Curran
  • 95,648
  • 35
  • 171
  • 253
  • It is in the context of generics that I first encountered the problem, but I wonder if including static methods in interfaces could be useful in other contexts, too? Is there a reason why things couldn't be changed? – Kramii Nov 03 '08 at 16:05
  • me too encounter this when implementing a generic class which require the parameter type to create itself with some parameters. Since the new() cannot take any. Did you figure out how to do this yet, Kramii? – Tom Dec 09 '09 at 18:31
  • 1
    @Kramii: Contracts for static APIs. I don't want an object instance, just a guarantee of a particular signature, eg. IMatrixMultiplier or ICustomSerializer. Funcs/Actions/Delegates as class members do the trick, but IMO this sometimes seems like overkill, and can be confusing for the unexperienced trying to extend the API. – David Cuccia May 09 '10 at 22:04
15

To the extent that interfaces represent "contracts", it seems quiet reasonable for static classes to implement interfaces.

The above arguments all seem to miss this point about contracts.

George
  • 1,268
  • 18
  • 28
  • 3
    I totally agree with this simple but effective answer. What would be interesting in "static interface" is that it would represent a contract. Maybe it should not be called a "static interface" but we still miss a construct. For example, check .NET's official doc about the ICustomMarshaler interface. It requires the class that implements it to "add a static method called GetInstance that accepts a String as a parameter and has a return type of ICustomMarshaler". That does seriously look like a "static interface" definition in plain english while I would prefer it in C#... – Simon Mourier Oct 27 '15 at 09:48
  • @SimonMourier That documentation could have been written more clearly, but you are misinterpreting it. It's not the ICustomMarshaler interface that requires the GetInstance static method. It is the [MarshalAs] code attribute that requires this. They are using the factory pattern to allow the attribute to get an instance of the attached marshaler. Unfortunately they completely forgot to include documenting the GetInstance requirement on the MarshalAs documentation page (it only shows examples using built-in marshaling implementations). – Scott Gartner Jun 20 '17 at 19:53
  • @ScottGartner - Don't get your point. https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler.aspx clearly states : "In addition to implementing the ICustomMarshaler interface, custom marshalers must implement a static method called GetInstance that accepts a String as a parameter and has a return type of ICustomMarshaler. This static method is called by the common language runtime's COM interop layer to instantiate an instance of the custom marshaler.". This is a definitely a static contract definition. – Simon Mourier Jun 20 '17 at 20:53
14

Interfaces specify behavior of an object.

Static methods do not specify a behavior of an object, but behavior that affects an object in some way.

John Kraft
  • 6,606
  • 4
  • 35
  • 52
  • 71
    Sorry.. I'm not sure that's right! An interface doesn't specify behavior. An interface defines a set of named operations. Two classes could implement an interface's method to behave in completely different ways. So, an interface doesn't specify behavior at all. The class that implements it does. – Scott Langham Nov 03 '08 at 17:27
  • 1
    Hope you don't think I'm being picky.. but I think it's an important distinction for anybody learning OO to understand. – Scott Langham Nov 03 '08 at 17:28
  • 4
    An interface is supposed to specify a contract that includes behavior and presentation. That's why changing the behavior of an interface call is a no-no as both are supposed to be fixed. If you have an interface where the call acts differently (i.e. IList.Add did a remove) it wouldn't be right. – Jeff Yates Nov 03 '08 at 18:03
  • 15
    Well, yes, you'd be warped in the head to define a method to behave incongruously to its name. If you had IAlertService.GetAssistance() though, it's behaviour could be to flash a light, sound an alarm, or poke in the eye with a stick. – Scott Langham Nov 04 '08 at 00:05
  • 1
    An implementation would also be able to write to a log file. This behaviour isn't specified in the interface. But, maybe you're right. The behaviour to 'get assistance' should really be respected. – Scott Langham Nov 04 '08 at 00:09
  • 1
    Elaborating on this from a language-agnostic point of view: interfaces are abstract types. Types are something which describes an instance, or value. Static classes are not true types, speaking in theoretical terms, as they cannot be instantiated. It then follows that static classes should/cannot have interfaces. – awdz9nld Nov 07 '12 at 19:52
  • @ScottLangham I look at those "named operations" as the behavior. How a class chooses to implement that behavior is irrelevant. In the example above, GetAssistance() is the behavior. How it does that is irrelevant to me; and that's the whole point. Classes are useless without behavior; unless they are simple data bags. – John Kraft Feb 25 '13 at 15:17
  • This is an old answer to an old question, but this is why I downvoted: If interfaces could enforce a specific behavior they wouldn't be nearly as useful. One of the most common reason for interfaces are to allow multiple child classes to implement different behavior for the same contract (for example, interface IStore => to memory, to disk, to a database, to NULL, etc.). The designer of an interface can (and should) document "expected" behavior and, at least, assumptions in document comments, but the interface cannot enforce it. In C#, in particular, you can't even limit exceptions. – Scott Gartner Jun 20 '17 at 19:44
  • As with most of the people that down-voted this throughout the years, you are confusing behavior with implementation. To use the silly animal/dog example, Bark is the behavior. The interface enforces the behavior of Bark, not the implementation of such behavior. A contract/interface defines behavior. Interfaces do not allow implementation of different behavior, they allow implementation of behavior differently. Barking is barking, regardless of the breed. It's all semantics and pedantics at this point. – John Kraft Jul 11 '17 at 21:13
9

Because the purpose of an interface is to allow polymorphism, being able to pass an instance of any number of defined classes that have all been defined to implement the defined interface... guaranteeing that within your polymorphic call, the code will be able to find the method you are calling. it makes no sense to allow a static method to implement the interface,

How would you call it??


public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
    public static void MyMethod() { //Do Something; }
}

 // inside of some other class ...  
 // How would you call the method on the interface ???
    MyClass.MyMethod();  // this calls the method normally 
                         // not through the interface...

    // This next fails you can't cast a classname to a different type... 
    // Only instances can be Cast to a different type...
    MyInterface myItf = MyClass as MyInterface;  
Charles Bretana
  • 131,932
  • 22
  • 140
  • 207
  • 1
    Other languages (Java, for example) allow static methods to be called from object instances, although you will get a warning that you should be calling them from a static context. – Chris Marasti-Georg Nov 03 '08 at 18:48
  • Allowing a static method to be called from an instance is allowed in .Net as well. That is a different thing. If a static method implemented an interface, you could call it WITHOUT an instance. THAT is what does not make sense. Remember you can't put implementation in an interface, it must be in the class. So if five different classes were defined to implement that interface, and each had a different implementation of this static method, which would the compiler use? – Charles Bretana Dec 30 '14 at 14:48
  • 1
    @CharlesBretana in the case of generics, the one for the type passed in. I see a lot of usefulness in having interfaces for static methods (or if you want, let's call them "static interfaces" and allow a class to define both static interfaces and instance interfaces). So if I have `Whatever() where T:IMyStaticInterface` I could call `Whatever()` and have `T.MyStaticMethod()` inside the `Whatever()` implementation without needing an instance. The method to call would be determined in runtime. You can do this via reflection, but there's no "contract" to be forced. – Jcl Mar 03 '15 at 14:42
4

Regarding static methods used in non-generic contexts I agree that it doesn't make much sense to allow them in interfaces, since you wouldn't be able to call them if you had a reference to the interface anyway. However there is a fundamental hole in the language design created by using interfaces NOT in a polymorphic context, but in a generic one. In this case the interface is not an interface at all but rather a constraint. Because C# has no concept of a constraint outside of an interface it is missing substantial functionality. Case in point:

T SumElements<T>(T initVal, T[] values)
{
    foreach (var v in values)
    {
        initVal += v;
    }
}

Here there is no polymorphism, the generic uses the actual type of the object and calls the += operator, but this fails since it can't say for sure that that operator exists. The simple solution is to specify it in the constraint; the simple solution is impossible because operators are static and static methods can't be in an interface and (here is the problem) constraints are represented as interfaces.

What C# needs is a real constraint type, all interfaces would also be constraints, but not all constraints would be interfaces then you could do this:

constraint CHasPlusEquals
{
    static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}

T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
    foreach (var v in values)
    {
        initVal += v;
    }
}

There has been lots of talk already about making an IArithmetic for all numeric types to implement, but there is concern about efficiency, since a constraint is not a polymorphic construct, making a CArithmetic constraint would solve that problem.

Jeremy Sorensen
  • 800
  • 1
  • 5
  • 12
  • Operators in C# are static, so this still doesn't make sense. – John Saunders Aug 13 '13 at 18:39
  • Thats the point, the constraint verifies that the TYPE (not instance) has the + operator (and by extension the += operator) and allows the template to be generated, then when the actual template substitution occures the object being used is guaranteed to be of a type that has that operator (or other static method.) So you can say: SumElements(0, 5); which would instantiate this: SumElements(int initVal, int[] values) { foreach (var v in values) { initVal += v; } }, which of course, makes perfect sense – Jeremy Sorensen Aug 13 '13 at 21:44
  • 1
    Remember it's not a template. It's generics, which is not the same as C++ templates. – John Saunders Aug 13 '13 at 21:46
  • @JohnSaunders: Generics aren't templates, and I don't know how they could reasonably be made to work with statically-bound operators, but in generic contexts there are many cases where it could be useful to specify that a `T` should have a *static* member (e.g. a factory that produces `T` instances). Even without runtime changes, I think it would be possible to define conventions and helper methods that would allow languages to implement such a thing as syntactic sugar in an efficient and interoperable fashion. If for each interface with virtual static methods there were a helper class... – supercat Dec 14 '13 at 18:51
  • ...then if `T` is constrained to `IFoo`, `T.CreateThing(paramString)` would become `IFoo_Helper.CreateThing(paramString)`, and within class `Fred` that implemnets `IFoo`, a definition of `static Fred IFoo.CreateThing(string st)` would tag the method so that the `IFoo_Helper` method could find it via Reflection the first time it was needed [future accesses would be via cached delegate]. – supercat Dec 14 '13 at 18:57
  • @supercat: I think I've actually seen a few examples like this. Where the only thing preventing a certain method from being `static` is the fact that it implements a member of an interface. – John Saunders Dec 14 '13 at 19:11
  • 1
    @JohnSaunders: The problem isn't that so much the method implements an interface, but rather that the compiler can't select a virtual method to call without having an object instance upon which to base the selection. A solution is to dispatch the "static interface" call not using virtual dispatch (which won't work) but instead using a call to a generic static class. Type-based generic dispatch doesn't require having an instance, but merely having a type. – supercat Dec 14 '13 at 20:53
3

Because interfaces are in inheritance structure, and static methods don't inherit well.

Joel Coehoorn
  • 362,140
  • 107
  • 528
  • 764
3

What you seem to want would allow for a static method to be called via both the Type or any instance of that type. This would at very least result in ambiguity which is not a desirable trait.

There would be endless debates about whether it mattered, which is best practice and whether there are performance issues doing it one way or another. By simply not supporting it C# saves us having to worry about it.

Its also likely that a compilier that conformed to this desire would lose some optimisations that may come with a more strict separation between instance and static methods.

AnthonyWJones
  • 178,910
  • 32
  • 227
  • 302
  • Interestingly, it is quite possible to call a static method by both Type ad Instance in VB.Net (even though the IDE gives a warning in the latter case). It doesn't appear to be a problem. You may be right about the optimisations. – Kramii Nov 03 '08 at 16:54
3

You can think of the static methods and non-static methods of a class as being different interfaces. When called, static methods resolve to the singleton static class object, and non-static methods resolve to the instance of the class you deal with. So, if you use static and non-static methods in an interface, you'd effectively be declaring two interfaces when really we want interfaces to be used to access one cohesive thing.

Scott Langham
  • 53,246
  • 34
  • 122
  • 193
  • This is an interesting POV, and is probably the one that the C# designers had in mind. I will think of static members in a different way from now on. – Kramii Nov 03 '08 at 17:00
3

To give an example where I am missing either static implementation of interface methods or what Mark Brackett introduced as the "so-called type method":

When reading from a database storage, we have a generic DataTable class that handles reading from a table of any structure. All table specific information is put in one class per table that also holds data for one row from the DB and which must implement an IDataRow interface. Included in the IDataRow is a description of the structure of the table to read from the database. The DataTable must ask for the datastructure from the IDataRow before reading from the DB. Currently this looks like:

interface IDataRow {
  string GetDataSTructre();  // How to read data from the DB
  void Read(IDBDataRow);     // How to populate this datarow from DB data
}

public class DataTable<T> : List<T> where T : IDataRow {

  public string GetDataStructure()
    // Desired: Static or Type method:
    // return (T.GetDataStructure());
    // Required: Instantiate a new class:
    return (new T().GetDataStructure());
  }

}

The GetDataStructure is only required once for each table to read, the overhead for instantiating one more instance is minimal. However, it would be nice in this case here.

1

Most people seem to forget that in OOP Classes are objects too, and so they have messages, which for some reason c# calls "static method". The fact that differences exist between instance objects and class objects only shows flaws or shortcomings in the language. Optimist about c# though...

Mar Bar
  • 407
  • 5
  • 11
1

OK here is an example of needing a 'type method'. I am creating one of a set of classes based on some source XML. So I have a

  static public bool IsHandled(XElement xml)

function which is called in turn on each class.

The function should be static as otherwise we waste time creating inappropriate objects. As @Ian Boyde points out it could be done in a factory class, but this just adds complexity.

It would be nice to add it to the interface to force class implementors to implement it. This would not cause significant overhead - it is only a compile/link time check and does not affect the vtable.

However, it would also be a fairly minor improvement. As the method is static, I as the caller, must call it explicitly and so get an immediate compile error if it is not implemented. Allowing it to be specified on the interface would mean this error comes marginally earlier in the development cycle, but this is trivial compared to other broken-interface issues.

So it is a minor potential feature which on balance is probably best left out.

John Saunders
  • 157,405
  • 24
  • 229
  • 388
1

Interfaces are abstract sets of defined available functionality.

Whether or not a method in that interface behaves as static or not is an implementation detail that should be hidden behind the interface. It would be wrong to define an interface method as static because you would be unnecessarily forcing the method to be implemented in a certain way.

If methods were defined as static, the class implementing the interface wouldn't be as encapsulated as it could be. Encapsulation is a good thing to strive for in object oriented design (I won't go into why, you can read that here: http://en.wikipedia.org/wiki/Object-oriented). For this reason, static methods aren't permitted in interfaces.

Jeff Yates
  • 58,658
  • 18
  • 135
  • 183
Scott Langham
  • 53,246
  • 34
  • 122
  • 193
  • 1
    Yes, a static in the interface declaration would be silly. A class should not be forced to implement the interface in a certain way. However, does C# restrict a class to implementing the interface using non-static methods. Does this make sense? Why? – Kramii Nov 03 '08 at 16:50
  • You can't use the keyword 'static'. There is no restriction though because you don't need the static keyword to write a method that behaves statically. Just write a method that doesn't access any of its object's members, then it will behave just like a static method. So, there is restriction. – Scott Langham Nov 03 '08 at 17:06
  • True Scott, but it doesn't allow someone to access that method in a static way, in another part of the code. Not that I can think of a reason you would want to, but that seems to be what the OP is asking. – Chris Marasti-Georg Nov 03 '08 at 17:41
  • Well, if you really felt the need you could write it as a static method for access in another part of the code, and just write the non-static method to call the static method. I could be wrong, but I doubt that's an objective of the questioner. – Scott Langham Nov 03 '08 at 23:46
1

FYI: You could get a similar behavior to what you want by creating extension methods for the interface. The extension method would be a shared, non overridable static behavior. However, unfortunately, this static method would not be part of the contract.

Daniel Auger
  • 12,072
  • 5
  • 46
  • 71
1

The fact that a static class is implemented in C# by Microsoft creating a special instance of a class with the static elements is just an oddity of how static functionality is achieved. It is isn't a theoretical point.

An interface SHOULD be a descriptor of the class interface - or how it is interacted with, and that should include interactions that are static. The general definition of interface (from Meriam-Webster): the place or area at which different things meet and communicate with or affect each other. When you omit static components of a class or static classes entirely, we are ignoring large sections of how these bad boys interact.

Here is a very clear example of where being able to use interfaces with static classes would be quite useful:

public interface ICrudModel<T, Tk>
{
    Boolean Create(T obj);
    T Retrieve(Tk key);
    Boolean Update(T obj);
    Boolean Delete(T obj);
}

Currently, I write the static classes that contain these methods without any kind of checking to make sure that I haven't forgotten anything. Is like the bad old days of programming before OOP.

Thomas Phaneuf
  • 196
  • 2
  • 7
  • This is an ancient question; these days, we try very hard to avoid opinion-based questions because they're difficult to answer authoritatively. The only good way to answer this would be to describe the reasons MS had, or demonstrably should have had, for doing it the way they did. – Nathan Tuggy Jul 26 '15 at 00:47
1

C# and the CLR should support static methods in interfaces as Java does. The static modifier is part of a contract definition and does have meaning, specifically that the behavior and return value do not vary base on instance although it may still vary from call to call.

That said, I recommend that when you want to use a static method in an interface and cannot, use an annotation instead. You will get the functionality you are looking for.

Daniel Barbalace
  • 1,049
  • 1
  • 16
  • 10
1

Static classes should be able to do this so they can be used generically. I had to instead implement a Singleton to achieve the desired results.

I had a bunch of Static Business Layer classes that implemented CRUD methods like "Create", "Read", "Update", "Delete" for each entity type like "User", "Team", ect.. Then I created a base control that had an abstract property for the Business Layer class that implemented the CRUD methods. This allowed me to automate the "Create", "Read", "Update", "Delete" operations from the base class. I had to use a Singleton because of the Static limitation.

0

I think the short answer is "because it is of zero usefulness". To call an interface method, you need an instance of the type. From instance methods you can call any static methods you want to.

mackenir
  • 9,910
  • 14
  • 62
  • 95
0

I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.

Since it's not available, I have taken to using non-static methods in the way shown below. Not exactly ideal, but I can't see any approach that makes more sense, at least not for me.

public interface IZeroWrapper<TNumber> {
  TNumber Zero {get;}
}

public class DoubleWrapper: IZeroWrapper<double> {
  public double Zero { get { return 0; } }
}
William Jockusch
  • 26,421
  • 48
  • 170
  • 299
0

As per Object oriented concept Interface implemented by classes and have contract to access these implemented function(or methods) using object.

So if you want to access Interface Contract methods you have to create object. It is always must that is not allowed in case of Static methods. Static classes ,method and variables never require objects and load in memory without creating object of that area(or class) or you can say do not require Object Creation.

0

Conceptually there is no reason why an interface could not define a contract that includes static methods.

For the current C# language implementation, the restriction is due to the allowance of inheritance of a base class and interfaces. If "class SomeBaseClass" implements "interface ISomeInterface" and "class SomeDerivedClass : SomeBaseClass, ISomeInterface" also implements the interface, a static method to implement an interface method would fail compile because a static method cannot have same signature as an instance method (which would be present in base class to implement the interface).

A static class is functionally identical to a singleton and serves the same purpose as a singleton with cleaner syntax. Since a singleton can implement an interface, interface implementations by statics are conceptually valid.

So it simply boils down to the limitation of C# name conflict for instance and static methods of the same name across inheritance. There is no reason why C# could not be "upgraded" to support static method contracts (interfaces).

Coder
  • 383
  • 3
  • 9
-1

When a class implements an interface,it is creating instance for the interface members. While a static type doesnt have an instance,there is no point in having static signatures in an interface.