从泛型 class 派生的 c# 问题

c# problem with deriving from generic class

以下正在工作 classes:

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>
{
}

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

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

    }
}

错误信息:

Error CS0311 The type 'BankDataEntryForm' cannot be used as type parameter 'T1' in the generic type or method 'CatalogManager'. Error CS0311 The type 'BankDataGridForm' cannot be used as type parameter 'T2' in the generic type or method 'CatalogManager'

非常感谢您的帮助。

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

Starting with the .NET Framework 4, Visual Basic and C# have keywords that enable you to mark the generic type parameters of interfaces and delegates as covariant or contravariant.

所以你可以尝试为那些 class.

制作界面
  • ICatalogDataEntryForm<out T> 对于 CatalogDataEntryForm<T>
  • ICatalogDataGridForm<out T> 对于 CatalogDataGridForm<T>

然后让那些class实现接口

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()
    {

    }
}

然后让CatalogManagerclass与那些接口

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

    }

}

c# online