C# Static interfaces - Take 2
By Jérémie Chassaing on Thursday, October 22, 2009, 15:11 - .Net Framework - Permalink
As Romain was pointing in the comments, I totally missed to tell where I wanted to go with this static interface things. Need more sleep these days…
So here it is.
No I don’t want to do this
The point was not to enable something like this :
int value = ICountable.Count;
Static interfaces have no implementation exactly like interfaces.
With interfaces, you need an instance (usually in a variable or member) to find the actual implementation and call it. With static interfaces, you need a type.
There are two ways to specify a type:
- with its type name (Sample4.Count)
- with a generic type parameter (T.Count)
I was also proposing a way to specify a type for extension methods.
Where it would be useful - operators
The reason why everybody is asking for static members in interfaces is ultimately to have operators in interfaces.
Imagine :
public static interface IArithmetic<T>
{
static T operator +(T x, T y);
static T operator -(T x, T y);
static T operator *(T x, T y);
static T operator /(T x, T y);
}
Now you can write generic code like :
public static T Power<T>(this T value, int count) where T : IArithmetic<T>
{
var result = T.Identity;
for (int i=0;i<count;i++)
result = result*value;
return result;
}
Cool !
This way, no need for the 20 overloads of Enumerable.Sum, it would work for any type presenting the expected static interface.
Comments
Yep, it makes more sense. You wish you could define static members in interfaces to:
- be able to use them from a constrained generic context
- allow static (static) extension methods -- extensions methods on types
Having a static member in an interface would pretty much say: this member has to exist in implementers, *and it must be static*.
I did feel like I needed something similar once. I was working on an object-object mapper and was thinking about an API to provide custom transformers/converters (in the most basic form, it would have been static methods).
Not sure such a feature has to be top prioritized though :)
@romain> there are surely more important things to add to the language... but it would extend the language in its static nature... whereas the current solution to avoid the Enumerable.Sum problem is to bypass static verification (using dynamic in C#4 or reflection...)
With operators would also bring conversion/cast operators, which would be extremely useful.
@Jimmy> Yes conversion/cast would avoid unnecessary cast to object in generic methods (especialy with value types).
The strange thing is that there are strange rules on the == operator that is resolved, based on type at compilation time... Don't understand why other operators don't behave the same...
I've been wishing for static interfaces for a long time now.
It seems like the more code I develop, the more I make classes similar to each other. Classes for models, classes for views, classes for database rows, classes for whatever. Anyway, I find that I make more and more static members on all of these classes and all of my model classes have the same static members. But, I cant interact with them in a generic way. Even though I can require all of my model classes to implement IModel, I still cant access the static functions on each model class in a generic way. Which really sucks because so much of what I do with the classes is done generically.
The only way I have overcome this is to create stupid singleton companion classes that contain the stuff I want to expose in a generic fashion, but that creates issues with encapsulation (if you are an OO purist).
anyway, I think that this is more than just a novel concept that they "could" implement, and I think it is way more valuable than half the stuff they added in 4.0, like dynamics, which destroy compile time checking. If I didnt care about compile time checking, I'd be using PHP or Python. Honestly.
On multiple occasions, I've wanted an interface to specify specific constructors... after submitting the suggestion to Connect.Microsoft.com I was informed that the constructors are effectively static methods.
So regarding additional use cases for interfaces to specify static methods: Constructors :)