Implicit Type Parameter for Implementing Type

A while ago I had an interesting twitter discussion with Chris Ammerman (@cammerman) about type parameters of generic interfaces (C#). Chris tweeted "I often encounter a situation where I want a generic interface, but the type param should ALWAYS be the type of the implementing class". One example of this is ICloneable. Would it ever be acceptable for ICloneable.Clone() to return an object of a type other than the implementing type of the interface? With ICloneable you will always want to cast the result of Clone() because most of the time you want The Real Thing® instead of System.Object. For that reason many people create their own generic interface:

public interface ICloneable<T>
{
T Clone();
}

public class Foo : ICloneable<Foo>
{
Foo Clone() { /* implement me */ }
}

This is still ugly. I want this instead:

public interface ICloneable
{
implementer Clone();
}

public class Foo : ICloneable
{
Foo Clone() { /* implement me */ }
}

implementer would be a keyword like base or this but it would not refer to an object but to a type. It would behave as an implicit type parameter to the interface. This would not only be convenient syntactic sugar. It would also make the use of the parameter explicit. You couldn't do class Foo : ICloneable<Bar> anymore.

List of Tweets:

you guys are freaky :) ...

you guys are freaky :) ... but you've may forgotten about the critical part: implementer may not be bound to interfaces. if you loose the generic-information inside the interface, how can you create eg extension-methods with the generic type? ...

public static ??? DoSomething(this ICloneable cloneable)
{
    /* how do i have access to the result-type of the .Clone-method? */
    var clonedInstance = cloneable.Clone();
    /* `var` must be translated into something generic upon compile-time ... and not the interface :) */
}

if you go for this instead

public static T DoSomething<T>(this T cloneable)
    where T : ICloneable
{
    var clonedInstance = cloneable.Clone();
    return clonedInstance;
}

you do loose the generic-information inside the where-constraint - this means that you can break the information with super/base-classes ...

Interesting

You have a point there. Good thing I didn't call Anders. He would have laughed at me (again). He can be so mean... ;-)

Powered by Drupal, an open source content management systemCreative Commons LicenseSyndicate content