开发者

c# generics on a method with the constraint that the type must be of "this" type

开发者 https://www.devze.com 2023-02-05 08:39 出处:网络
I have a C# class hierarchy with a common base type and two derived types.I want to declare an abstract method on the base class something like this :

I have a C# class hierarchy with a common base type and two derived types. I want to declare an abstract method on the base class something like this :

public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass

... and I want this method to be implemented in the derived classes such that T is the type of that derived type, for each of the derived types, ie, in derived class A:

public override IEnumerable<A> GetSiblings<A>开发者_开发技巧() { ... }

... and in derived class B ...

public override IEnumerable<B> GetSiblings<B>() { ... }

Put another way, each derived class must implement the method so that it returns an IEnumerable of items of the same type. Is there any way to implement this in C# ?


Well, you can hardly call a method generic if it only accepts a parameter of a single type, and your method signatures will have different return types which isn't allowed. Why don't you define an interface for all of these classes and simply return an IEnumerable<IMyClass>?


You can't do this because the return types are different. Simple as that. The reason is if you create an instance of A and stuff it into your base class(cast it) then the return type will be wrong.

You might be able to to use new instead but that might break your hierarchy.


This is not supported by the type system. It's a common enough problem, represented often as

class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired

But not a problem that has as yet been acted upon by the appropriate parties (be it the framework providers or C# team, not sure who).

Until it passes the critical "worth it" test as determined by costs (and opportunity costs) versus benefits, you'll have to work around it.


I found the solution. Apparently in C# 4.0, generic parameter types can be covariant, so what I've posted above will work. C# 3.5 or lower, and it doesn't work. Took a lot of Googling.

0

精彩评论

暂无评论...
验证码 换一张
取 消