有什么方法可以限制类型变量可能包含的类型吗?

时间:2014-04-03 19:42:40

标签: c# .net types clr

我的代码类似于以下内容。它将整数与类型相关联。我想使用这个字典来查找给定整数的类型,然后实例化该类型。

Dictionary<int, Type> RegistrationMethods;

RegistrationMethods = new Dictionary<int, Type>();
RegistrationMethods.Add(1, typeof(RegistrationProvider_01));
RegistrationMethods.Add(2, typeof(RegistrationProvider_02));

问题:我的所有类型都实现了IRegistrationMethod。有没有办法声明我的字典,以便它只能容纳实现此接口的类型?这将使我的代码更安全。

感谢您的任何提示。

3 个答案:

答案 0 :(得分:6)

如果你只想创建它们,你可以这样做:

Dictionary<int, Func<IRegistrationMethod>> RegistrationMethods;
RegistrationMethods.Add(1, () => new RegistrationProvider_01());

或者你可以要求通过方法添加所有元素:

public void AddRegistrationMethod<T>(int i) where T : IRegistrationMethod, new()
{
    RegistrationMethods.Add(i, typeof(T));
}

答案 1 :(得分:1)

  

我的所有类型都实现了IRegistrationMethod。是否有任何方法可以解析我的字典,以便它只能保存实现此接口的类型?这将使我的代码更安全。

您可以为Dictionary创建包装类:

public class WrapperDictionary
{
    private Dictionary<int, Type> dictionary;

    public WrapperDictionary()
    {
        dictionary = new Dictionary<int, Type>();

    }

    public bool Add(int key, Type value)
    {
        if (!dictionary.ContainsKey(key) &&
            value.IsAssignableFrom(typeof (IRegistrationMethod)))
        {
            dictionary.Add(key, value);
            return true;
        }
        else return false;
    }

    public Type this[int key]
    {
        get
        {
            if (dictionary.ContainsKey(key)) return dictionary[key];
             /* throw exception or return null */
        }

    }
}

为了创建给定类型的实例,您可以使用Activator.CreateInstance方法:

var dict = new WrapperDictionary();

dict.Add(2, typeof(RegistrationProvider_01));

var type = dict[2];

var instance = Activator.CreateInstance(type);

答案 2 :(得分:1)

您不能对Type强制执行此限制,因此也不能在Dictionary<…, Type>上强制执行此限制,但您可以将此类字典包装在专门类型中:

class RestrictedTypeDictionary<TRestriction>
{
    public RestrictedTypeDictionary()
    {
        this.internalDictionary = new Dictionary<int, Type>();
    }

    private readonly Dictionary<int, Type> internalDictionary;

    public void Add(int key, Type value)
    {
        if (!typeof(TRestriction).IsAssignableFrom(value))  // <- that's the important bit
        {
            throw new ArgumentOutOfRangeException("value");
        }
        internalDictionary.Add(key, value);
    }

    public Type this[int key]
    {
        get
        {
            return internalDictionary[key];
        }
    }

    …
}

然后,您可以使用RestrictedTypeDictionary<IRegistrationMethod>代替Dictionary<int, Type>来确保只能添加​​Type值来表示从IRegistrationMethod派生的类型的约束。

关于您的奖金,如果任何类型T使用默认构造函数,您可以使用Activator.CreateInstance(typeof(T))轻松创建该类型的实例。