[英]C# Generics, Abstract Classes, and Bounded Wildcards
在使泛型在C#中工作时,我有一个小问题:
我有以下课程:
public abstract class OphControl<TDataModel> : Control
where TDataModel : OphDataModel, new()
{
/// <summary>
/// The data model for this control.
/// </summary>
public TDataModel DataModel { get; private set; }
public IEnumerable<OphControl<OphDataModel>> OphControls {
get {
return Controls.Cast<Control>().Where(control => control is OphControl<OphDataModel>).Cast<OphControl<OphDataModel>>();
}
}
protected OphControl() {
DataModel = new TDataModel();
}
}
我的问题是,由于OphDataModel
是抽象的,因此OphControls
属性不会编译,因此我想在编译时不能确定OphDataModel具有零参数的公共构造函数(请注意TDataModel
的new()
约束)。
我什至不确定这是否是正确的解决方法。 我真正想要的是类似OphControl<? extends OphDataModel>
东西OphControl<? extends OphDataModel>
从Java OphControl<? extends OphDataModel>
。 我尝试添加out
我的TDataModel
在类的声明,但它告诉我只能代表和接口可以有协变类型参数。
那么我如何避开这个泡菜?
这里有些混乱的事情。 首先, OphControl<TDataModel>
不是从OphControl<OphDataModel>
派生的,并且您对out
关键字(协方差/ OphControl<OphDataModel>
是正确的,它们只能与委托和接口一起使用。 由于它不是基类,因此您可能无法强制转换。
与Java不同,c#不支持通用通配符( ...<? extends ...>
)。 解决方法是创建一个非通用版本并使它成为基类。
public abstract class OphControl : Control { ... }
public abstract class OphControl<TDataModel> : OphControl
where TDataModel : OphDataModel, new() { ... }
不幸的是,基类不能具有DataModel属性,因为c#也不支持协变返回类型。
至少你可以拥有
public IEnumerable<OphControl> OphControls {
get {
return Controls.OfType<OphControl>();
}
}
我只需要更改OphControls
的通用参数OphControls
:
public IEnumerable<OphControl<TDataModel>> OphControls {
get {
return Controls.Cast<Control>().Where(control => control is OphControl<TDataModel>).Cast<OphControl<TDataModel>>();
}
}
这应该可以编译 ,但是在不了解您的类的情况下,很难说这是否正确
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.