从泛型 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 所说 DataEntryControl
与 BankDataEntryControl
不同,尽管它们是继承关系。
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>
{}
BankDataGridForm
和 BankDataEntryForm
无需更改。
public class BankDataGridForm : CatalogDataGridForm<BankDataGridControl>
{
}
public class BankDataEntryForm : CatalogDataEntryForm<BankDataEntryControl>
{
}
public class BankManager : CatalogManager<BankDataEntryForm, BankDataGridForm,CatalogBusinessObject>
{
public BankManager()
{
}
}
然后让CatalogManager
class与那些接口
签约
public class CatalogManager<T1, T2, T3> where T1 : ICatalogDataEntryForm<DataEntryControl>, new()
where T2 : ICatalogDataGridForm<DataGridControl>, new()
where T3 : CatalogBusinessObject
{
public CatalogManager()
{
}
}
以下正在工作 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 所说 DataEntryControl
与 BankDataEntryControl
不同,尽管它们是继承关系。
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>
{}
BankDataGridForm
和 BankDataEntryForm
无需更改。
public class BankDataGridForm : CatalogDataGridForm<BankDataGridControl>
{
}
public class BankDataEntryForm : CatalogDataEntryForm<BankDataEntryControl>
{
}
public class BankManager : CatalogManager<BankDataEntryForm, BankDataGridForm,CatalogBusinessObject>
{
public BankManager()
{
}
}
然后让CatalogManager
class与那些接口
public class CatalogManager<T1, T2, T3> where T1 : ICatalogDataEntryForm<DataEntryControl>, new()
where T2 : ICatalogDataGridForm<DataGridControl>, new()
where T3 : CatalogBusinessObject
{
public CatalogManager()
{
}
}