在C#中,我试图将私有泛型变量存储在通过泛型方法传入的非泛型类中。 泛型方法应该将子类转换为基类类型。
以下是此问题的示例:
class BaseModel { }
class DerivedModel : BaseModel { }
class Data<T> where T : BaseModel { }
// Class is NOT generic
class DataConsumer
{
// How do I set this to generic?
private Data<BaseModel> data;
public void Set<T>(Data<T> data) where T : BaseModel
{
// Compile time error:
// Cannot convert source type 'Generic.Data<T>
// to target type 'Generic.Data<Generic.BaseModel>'
this.data = data;
}
}
答案 0 :(得分:4)
这是因为您尝试将更多派生类型Data<T>
分配给基类型Data<BaseModel>
,这在通用类中是不允许的。
您有两种选择:
1-制作DataConsumer
通用:
class DataConsumer<T> where T : BaseModel
{
private Data<T> data;
public void Set(Data<T> data)
{
this.data = data;
}
}
2-或,使Data
成为界面而非类,并使用T
关键字将out
标记为协变类型:
interface IData<out T> where T : BaseModel { }
class DataConsumer
{
private IData<BaseModel> data;
public void Set<T>(IData<T> data) where T : BaseModel
{
this.data = data;
}
}
答案 1 :(得分:0)
this.data
的类型为Data<BaseModel>
,而函数参数data
的类型为Data<T : BaseModel>
。
您的示例首先会破坏泛型的整个目的,但您可以将Set()
方法声明为非泛型方法,并强制客户端执行强制转换。
private Data<BaseModel> data;
public void Set(Data<BaseModel> data)
{
this.data = data;
}
作为旁注,如果您声明所涉及的所有实体都是通用的,那么约束只允许您通过BaseModel
合同操纵对象,所以我无法看到显然演员是必要的。