2014-04-03 24 views
1

我有类似于以下代码。它将整数与类型关联。然后我想使用这个字典查找给定整数的类型,然后实例化该类型。任何方式来限制类型变量可能持有的类型?

Dictionary<int, Type> RegistrationMethods; 

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

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

感谢您的任何提示。

回答

7

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

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

对。我希望有更直接的东西。但是,除此之外,这第一种方法将工作得很好。谢谢。 –

+0

@Selman22你将如何添加一个类型*没有*实现接口使用任何解决方案? – Servy

1

我的所有类型的实现IRegistrationMethod:

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

或者你可能需要的所有元素,通过一种方法来添加。有没有什么方法来删除我的字典,以便它只能保存实现此接口的类型?这将使我的代码更安全。

您可以为您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); 
+0

这不会增加静态类型的安全性,这是问题的表达目标。 – Servy

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))轻松创建该类型的实例。

相关问题