Search

Add a concept of 'static interface' for use with generics by Lucas C1

Closed
as Postponed Help for as Postponed

33
Sign in to vote
1
Sign in to vote
Sign in
to vote
Type: Suggestion
ID: 90732
Opened: 8/30/2004 2:10:40 PM
Access Restriction: Public
0
Workaround(s)
When working with generics, for example MyThingy<T>, quite often the desire arises to somehow define a set of static methods that can be called on T. For nonstatic methods one can use interface (class MyThingy<T> where T:MyInterface), but this obviously doesn't work with static methods, because an interface cannot define static methods.

And for a reason: consider a class MyClass that implements a (hypothetical) interface IExample that defines a static method Method(). How would you call this? There is simply no way, other than calling MyClass.Method(), at which point the advantage of defining the interface is lost, because you need to know the name of the class.

However, with the introduction of generic arguments, a mechanism to call such 'static interface methods' suddenly *does* exist. To me, the following code, though currently invalid, could make sense (note that in this example the 'interface' is a generic too; this is just to exemplify the most important application I see (factories), but is not necessary for the principle:

interface IFactory<T> {static T Create(string spec);}
class FooMaker<T,F> where F: IFactory<T> {
public T Generate(string spec) {
T t = F.Create(spec); // note the call on F, not an instance of F
DoSomethingWith(t);
return t;
}
}

I choose to use the keyword 'interface' here, because it is similar in functionality, but I realize that this use may be too different, and another keyword should be choosen.

Note that this proposal is rather generic, and could be used as a solution toward a suggestion I proposed before, involving improving the 'new()' constraint: FDBK11721 ( http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=9a8e58ee-1371-4e99-8385-c3e2a4157fd6 ) And also to provide a solution for the suggestion proposed by Ben Monroe in FDBK11253 ( http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=e74396d0-0ec8-465d-b505-9c64cce45d2a ), about operators on generics.
Details (expand)
Product Language
English
Version
Visual Studio 2005 Beta 1
Category
Language/Compiler
Operating System
Windows XP Professional
Operating System Language
English
Proposed Solution
See the example in the problem statement, with the caveat that the keyword 'interface' may need to change, for instance into 'static interface'.
Benefits
Faster Development
Other Benefits
Faster Development
File Attachments
0 attachments
Sign in to post a comment.
Posted by Microsoft on 9/3/2004 at 9:35 AM
Lucas

thanks for your suggestion. A number of other people have suggested variations of this theme.

We are actively looking at revising this aspect of generic constraints, but it probably won't be in the upcoming release. Sorry.

Santosh
Posted by Ahimoth on 6/11/2008 at 1:20 PM
Has there been any movement on supporting static interface members for the exact scenario Lucas posted? Its been almost 4 years since this was posted as a suggestion and then marked as Postponed. This would be extremely useful for certain factory scenarios.
Posted by seer1 on 12/12/2008 at 2:09 AM
I'm just downloading Visual Studio 2010 CTP to check if something has changed in this subject.
I just want to add another benefits aside from those pointed by Lucas and Ahimoth:
- (at last) testability of static methods: we can create mock types and pass it to generic methods
- with this mechanism we can replace Dependency Injection (with all its advantages) in a much "cleaner" way - of course when there is no need to evaluate the type on runtime

Please Microsoft, add this feature to C#(and CLR) 4.0
Posted by Ibasa on 3/26/2009 at 9:01 AM
Adding the ability for generic constraints to define static methods (and operators) would bring generics up to par with c++ template methods while remaining type safe and easy to understand.

This would also allow for another oft asked for INumeric addition to the framework, which would allow format independent maths. For example if I write a Vector4 class in C++ I can have a Vector4<float> a Vector4<int>, or in a bad case any other class that defines + - * and / even if its not really a number. In C# we have to choose a format (normally float or double) and stick with it, adding INumeric (or SNumeric, see later) and static methods on generic constraints would allow C# to define Vector4<float>, Vector4<int> or any other numeric type.

A solution to this would be to have interfaces stay how they are now. And add a new static interface (Prefixed with S instead of I). Static interfaces could only be inherited from and used on generic constraints. A static interface could only define constructors and static methods/operators.

public static interface SExample
{
    SExample(string value);
    
    static int StaticMethod(int a, int b);
    
    static SExample operator + (SExample left, SExample right);
    
    static implicit operator double(SExample value);
    static explicit operator SExample(double value);
}

When you override the static interfaces all occurrences of the static interface name are overwritten with your type name.

public class Example : SExample
{
    public Example(string value) { ...stuff... }
    
    public static int StaticMethod(int a, int b) { ...stuff... }
    
    public static Example operator + (Example left, Example right) { ...stuff... }
    
    public static implicit operator double(Example value) { ...stuff... }
    public static explicit operator Example(double value) { ...stuff... }
}

You can then use Example with any generic method/type that is constrained to SExample. As its only used as a constraint no virtual lookup needs to be done as the type will be know at compile time.

Is this possible? It would really make generic so much more powerfull.
Posted by Ibasa on 3/27/2009 at 6:15 AM
normal interfaces. Class that inherit from the interface have to define those constructors and methods, replacing the interface type with their type (like my last post). However the constructors and static methods can only be looked up on a generic type constrained to that interface, but not to an instance of the interface (say passed to a method).

So this would be legal as all the methods could be looked up at compile time

T Method<T>(T value) where T : IInterfaceWithStaticMethodsAndConstructors
{
    T otherValue = new T(5.0); //Look up the type T and find its constructor that matches the interface constructor
    return T.StaticMethod(value, otherValue); //Loop up type T and find the static method that matches the interface static method
}

While this would be illegal as it would require a virtual lookup of a static method (not really possible)

IInterfaceWithStaticMethodsAndConstructors Method(IInterfaceWithStaticMethodsAndConstructors value)
{
    IInterfaceWithStaticMethodsAndConstructors otherValue = new IInterfaceWithStaticMethodsAndConstructors(5.0); //What type should be created?
    return IInterfaceWithStaticMethodsAndConstructors.StaticMethod(value, otherValue); //What static method should be called?
}

Can we please get some feedback on this issue?
Posted by Thaina on 11/23/2009 at 4:38 AM
Whenever you add this feature to .Net Framework. I request interface INumber and attach to all numeric type too.

Also I think you should allow interface constructor and replace it with where T : new().
Or at least. please make new(Can contain user-defined parameter)

It'll make our generic life easier.
Posted by Ibasa on 12/16/2009 at 10:40 AM
What would be even better is if they had number classes like Haskel.
A base interface called INumber, and then derived interfaces IReal(or IFloating) and IIntegral.