views:

9605

answers:

12

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

    ....

 }

[Edited to include an example]

A: 

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

Joel Coehoorn
+2  A: 

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 added 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
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
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
@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
+13  A: 

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
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
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
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
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
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
+14  A: 

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
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
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
+1  A: 

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
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
A: 

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.

Scott Langham
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
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
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
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
A: 

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
A: 

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
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
A: 

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  A: 

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 I suspect, a CS grad):

...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 it's usefulness.

Mark Brackett
Excellent, this is the answer that I wanted to write - I just didn't know the implementation detail.
Chris Marasti-Georg
+2  A: 

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
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
+1  A: 

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.