Ограничение нескольких типов в экземпляре Generic Collection - PullRequest
1 голос
/ 31 января 2011

Я хочу создать экземпляр универсальной коллекции (в данном случае это Словарь), но в объявлении универсального типа я хочу ограничить тип параметра более чем одним классом.

Вот пример кода:

У меня есть много классов с этим объявлением:

public class MyClass1 : UserControl, IEspecialOptions
public class MyClass2 : UserControl, IEspecialOptions, IOtherInterface

и т.д.

Вот что я хочу:

Dictionary<int, T> where T:UserControl, IEspecialOptions myDicc = new Dictionary<int, T>();

Это выглядит очень хорошо, но не компилируется.

Знаете ли вы, как противопоставить второй параметр ингарации из 2 классов / интерфейсов?

Я ограничен .net 2.0

Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 31 января 2011

Вы не можете. Но вы можете создать абстрактный класс, который наследует UserControl и реализует IEscpecialOptions, а затем ограничивает универсальный параметр для абстрактного типа.

3 голосов
/ 31 января 2011

Вы должны указать ограничение на уровне метода или класса, который вводит T, а не при объявлении вашей переменной.

class myDictClass<T> : where T:UserControl,IEspecialOPtions
{
  Dictionary<int,T> myDicc;
}
1 голос
/ 31 января 2011

Просто создайте собственного предка Dictionary<TKey,TValue>, чтобы ввести ограничение. Как это:

public class CustomControlDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    where TValue : UserControl, IEspecialOptions
{
    // possible constructors and custom methods, properties, etc.
}

Тогда вы сможете использовать его в своем коде так, как хотите:

// this compiles:
CustomControlDictionary<int, MyClass1> dict1 = new CustomControlDictionary<int, MyClass1>();
CustomControlDictionary<int, MyClass2> dict2 = new CustomControlDictionary<int, MyClass2>();

// this fails to compile:
CustomControlDictionary<int, string> dict3 = ...;

В случае, если параметр типа T из вашего примера предоставлен извне, вы, естественно, должны ввести ограничение типа на уровне окружающего класса.

public class MyCustomControlContainer<T> where T : UserControl, IEspecialOptions
{
    // this compiles:
    private CustomControlDictionary<int, T>;
}

Примечание. Если вы хотите смешать экземпляры MyClass1 и MyClass2 в одном и том же словаре, вам необходимо ввести общего предка для них, наследуя от UserControl и реализуя IEspecialOptions. В этом случае правильный путь будет правильным.

...