简体   繁体   中英

Multiple type constraint in Generic Collection instance

I want to instantiate a generic collection (a Dictionary in this case) but in the generic type declaration I want constraint the parameter type to more then 1 class.

Here is the example code:

I have many classes with this declaration:

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

etc.

This is what I want:

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

This looks very nice but don't compile.

Do you know how to contraint the second parameter to inherate from 2 classes/interfaces?

I'm limited to .net 2.0

Thanks in advance

YOu need to specify the contraint at the method or class level that introduces T, not when declaring your variable.

class myDictClass<T> : where T:UserControl,IEspecialOPtions
{
  Dictionary<int,T> myDicc;
}

You cannot. But you can create an abstract class that both inherits UserControl and implements IEscpecialOptions and then constraint the generic parameter to be of the abstract type.

Just make a custom ancestor of Dictionary<TKey,TValue> to introduce the constraint. Like this:

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

Then you will be able to use it in your code like you want:

// 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 = ...;

In case the type parameter T from your example is provided from outside, you have to, quite naturally, introduce the type constraint at the surrounding class level.

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

Note: In case you'd want to mix both MyClass1 and MyClass2 instances in the same dictionary, you'd have to introduce a common ancestor for them, inheriting from UserControl and implementing IEspecialOptions . An abstract class would be the right way in that case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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