[英]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.