Reputation: 459
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'. Error CS0311 The type 'BankDataGridForm' cannot be used as type parameter 'T2' in the generic type or method 'CatalogManager'
Many thanks for your help.
Upvotes: 1
Views: 50
Reputation: 46239
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.
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.
so you can try to make the interface for those class.
ICatalogDataEntryForm<out T>
for CatalogDataEntryForm<T>
ICatalogDataGridForm<out T>
for 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.
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
public class CatalogManager<T1, T2, T3> where T1 : ICatalogDataEntryForm<DataEntryControl>, new()
where T2 : ICatalogDataGridForm<DataGridControl>, new()
where T3 : CatalogBusinessObject
{
public CatalogManager()
{
}
}
Upvotes: 2