C # проблема с производным от универсального класса - PullRequest
0 голосов
/ 11 ноября 2018

Ниже приведены рабочие классы:

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» не может использоваться как тип параметр 'T1' в универсальном типе или методе 'CatalogManager'. Ошибка CS0311 Тип «BankDataGridForm» нельзя использовать в качестве типа параметр 'T2' в универсальном типе или методе 'CatalogManager'

Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 11 ноября 2018

Проблема заключается в Ковариантности и Контравариантности в Обобщениях , как говорят SLaks DataEntryControl не то же самое, что BankDataEntryControl, хотя Они являются наследственными отношениями.

Начиная с .NET Framework 4, в Visual Basic и C # есть ключевые слова, позволяющие пометить параметры универсального типа интерфейсов и делегатов как ковариантные или контравариантные.

так что вы можете попытаться создать интерфейс для этого класса.

  • ICatalogDataEntryForm<out T> для CatalogDataEntryForm<T>
  • ICatalogDataGridForm<out T> для CatalogDataGridForm<T>

тогда пусть эти классы реализуют интерфейс

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 заключить класс с этими интерфейсами

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

    }

}

c # online

...