从泛型类派生的C#问题

时间:2018-11-11 15:29:09

标签: c# generics implicit-conversion

以下是工人阶级:

public class CatalogManager<T1, T2, T3> where T1 : CatalogDataEntryForm<DataEntryControl>, new()
                                        where T2 : CatalogDataGridForm<DataGridControl>, new()
                                        where T3 : CatalogBusinessObject
{
    public CatalogManager()
    {
        _DataGridFrom = new T2();
        InitGridformToolbarItemeEvents();
    }

}

public class BankDataEntryForm : CatalogDataEntryForm<BankDataEntryControl>
{
}

public class BankDataGridForm : CatalogDataGridForm<BankDataGridControl>
{
}

但是,下面的派生类在抱怨错误:

public class BankManager : CatalogManager<BankDataEntryForm, BankDataGridForm, BankBo>
{
    public BankManager()
    {

    }
}

错误消息:

  

错误CS0311无法将类型'BankDataEntryForm'用作类型   通用类型或方法“ CatalogManager”中的参数“ T1”。错误CS0311无法将类型'BankDataGridForm'用作类型   通用类型或方法“ CatalogManager”中的参数“ T2”

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

问题是Covariance and Contravariance in Generics,因为SLaks说DataEntryControlBankDataEntryControl不同,尽管它们是继承关系。

  

从.NET Framework 4开始,Visual Basic和C#的关键字使您可以将接口和委托的通用类型参数标记为协变或逆变。

所以您可以尝试为这些类创建接口。

  • ICatalogDataEntryForm<out T> for CatalogDataEntryForm<T>
  • ICatalogDataGridForm<out T> for CatalogDataGridForm<T>

然后让那些类实现接口

public interface ICatalogDataEntryForm<out T> 
{ }

public interface ICatalogDataGridForm<out T> 
{ }

public class CatalogDataEntryForm<T> : ICatalogDataEntryForm<T>
{ }
public class CatalogDataGridForm<T> : ICatalogDataGridForm<T>
{}

BankDataGridFormBankDataEntryForm无需更改。

public class BankDataGridForm : CatalogDataGridForm<BankDataGridControl>
{ 
}
public class BankDataEntryForm : CatalogDataEntryForm<BankDataEntryControl>
{
}

public class BankManager : CatalogManager<BankDataEntryForm, BankDataGridForm,CatalogBusinessObject>
{
    public BankManager()
    {

    }
}

然后让CatalogManager类与这些接口收缩

public class CatalogManager<T1, T2, T3> where T1 : ICatalogDataEntryForm<DataEntryControl>, new()
                                       where T2 : ICatalogDataGridForm<DataGridControl>, new()
                                       where T3 : CatalogBusinessObject
{
    public CatalogManager()
    {

    }

}

c# online