繁体   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