限制类型变量可能包含的类型的任何方法

本文关键字:类型 任何 方法 包含 类型变量 | 更新日期: 2023-09-27 17:56:24

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

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

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

感谢您的任何提示。

限制类型变量可能包含的类型的任何方法

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

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));
}

我的所有类型都实现了 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);
你不能对

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>来确保只能添加表示从IRegistrationMethod派生类型的Type值的约束。

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

相关文章: