简体   繁体   English

从泛型类派生的C#问题

[英]c# problem with deriving from generic class

Below are working 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>
{
}

However, below derived class is complaining with error: 但是,下面的派生类在报错:

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

    }
}

Error message: 错误信息:

Error CS0311 The type 'BankDataEntryForm' cannot be used as type parameter 'T1' in the generic type or method 'CatalogManager'. 错误CS0311类型'BankDataEntryForm'不能用作通用类型或方法'CatalogManager'中的类型参数'T1'。 Error CS0311 The type 'BankDataGridForm' cannot be used as type parameter 'T2' in the generic type or method 'CatalogManager' 错误CS0311类型'BankDataGridForm'不能用作通用类型或方法'CatalogManager'中的类型参数'T2'

Many thanks for your help. 非常感谢您的帮助。

The issue is a Covariance and Contravariance in Generics as SLaks say DataEntryControl is not the same as BankDataEntryControl , although They are an inheritance relationship. 问题是泛型中协方差和协方差,因为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. 从.NET Framework 4开始,Visual Basic和C#具有使您可以将接口和委托的通用类型参数标记为协变或相反的关键字。

so you can try to make the interface for those class. 因此您可以尝试为这些类创建接口。

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

then let those class implement interface 然后让那些类实现接口

public interface ICatalogDataEntryForm<out T> 
{ }

public interface ICatalogDataGridForm<out T> 
{ }

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

BankDataGridForm and BankDataEntryForm no need to change. BankDataGridFormBankDataEntryForm无需更改。

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

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

    }
}

Then let CatalogManager class contract with those interface 然后让CatalogManager类与那些接口收缩

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

    }

}

c# online C#在线

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM