C#中是否有任何方法可以实现以下目的:
class MyClass<T> where T : BaseTypeInner {}
class BaseTypeInner {}
class A : BaseTypeInner {}
class B : BaseTypeInner {}
void Main()
{
MyClass<BaseTypeInner> variant;
variant = new MyClass<A> (); // ERROR: Cannot implicitly convert type 'UserQuery.MyClass<UserQuery.A>' to 'UserQuery.MyClass<UserQuery.BaseTypeInner>'
variant = new MyClass<B> ();
}
答案 0 :(得分:3)
在C#中,只有接口可以是变体。引用C#规范:
变体类型参数列表只能出现在接口和委托类型上。
因此,您可以声明一个通用的协变接口IBaseClass<out T>
,让BaseClass<T>
实现它,然后转换为IBaseClass<BaseTypeInner>
而不是转发给类。
interface IMyClass<out T> where T : BaseTypeInner { }
class MyClass<T> : IMyClass<T> where T : BaseTypeInner { }
IMyClass<BaseTypeInner> variant;
variant = new MyClass<A>(); // works just fine
variant = new MyClass<B>();
答案 1 :(得分:0)
一种可能的解决方案是为基本泛型类型提供基类型:
class BaseType {}
class MyClass<T> : BaseType where T : BaseTypeInner {}
class BaseTypeInner {}
class A : BaseTypeInner {}
class B : BaseTypeInner {}
void Main()
{
BaseType variant;
variant = new MyClass<A> ();
variant = new MyClass<B> ();
}
但是,这并不是一个好主意,因为我使用的是较低级的,并非通用的,所以我失去了使用类型参数获得的所有细节和限制。
答案 2 :(得分:0)
不,但是可以提供自定义CastUp
/ CastDown
方法来实现此目的。 ImmutableArray<T>
,.NET BCL的一部分,does this。