簡體   English   中英

C#泛型,抽象類和有界通配符

[英]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具有零參數的公共構造函數(請注意TDataModelnew()約束)。

我什至不確定這是否是正確的解決方法。 真正想要的是類似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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM