2009-12-04 89 views
5

有没有人听说过使用类型作为键并支持继承的“类型字典”?类型字典?

在我的申请,我想有从类型功能的字典,有点像这样:

Dictionary<Type, Func<object, object>> Transformers; 

的想法是,它会根据使用以某种方式变换对象,其键入:

// Transform an object 'obj' 
object result = Transformers[obj.GetType()](obj) 

普通字典的缺点是类型必须完全匹配。因此,如果我已经为IList < T>写了一个变压器,将它放入变形金刚字典中是没有用的,因为没有物体具有IList < T>(仅T [],列表< T>等)。换句话说,如果obj是列表< T>,则IList < T>的变换器将不会通过普通字典中的查找找到。

假设有一个TypeDictionary < TValue>中没有这样的事情,我可能会考虑写一个,如果它不是太难。任何想法如何实现?

回答

2

您应该可以使用带有custom comparer的字典,它使用Type.IsAssignableFrom来比较密钥。

更新:正如Qwertie指出的,这不起作用,因为您无法实现基于类型,其接口和祖先类的可重复哈希码计算。 His answer通过反复对类型,接口和祖先类进行哈希表查找,直到找到匹配项为止,提供了一种可能的解决方案。

与解决方案的唯一问题是你没有任何办法来指定哪些匹配时有多个匹配服用。如果您需要这种灵活性和控制力,我建​​议您考虑chain-of-responsibility设计模式。每个变压器可能是链条中的一个环节,它负责确定它是否可以应用于物体。如果不是,它会将请求传递到下一个链接。链中变压器的顺序决定了优先级。你失去了哈希表的速度,但是由于多次查找,你无论如何都失去了一些速度。

+1

这是行不通的。 IEqualityComparer对于从A派生并实现IA和IB的类B返回哪个哈希码?另外,请记住词典应该能够同时保存'List ','IList '和'object'的键。 – Qwertie 2009-12-04 18:20:29

+0

你说得对,我没有想到通过。 – 2009-12-04 18:56:08

+0

@Qwertie在这种情况下,如果字典中有几个匹配类型的话,你的字典会返回什么?它是否应该返回所有的事件,只有最专业的等等? – 2009-12-04 19:04:17

1

的字典二传手没有不同的语义从一个普通的字典,所以一个方法是使用一个标准的字典,专门查找它发生对我说:

public class TypeDictionary<TValue> : Dictionary<Type, TValue> 
{ 
    public new TValue this[Type key] 
    { 
     get { 
      TValue value; 
      if (TryGetValue(key, out value)) 
       return value; 
      throw new KeyNotFoundException("Not found: " + key.Name); 
     } 
    } 
    public new bool TryGetValue(Type key, out TValue value) 
    { 
     if (base.TryGetValue(key, out value)) 
      return true; 

     Type[] interfaces = key.GetInterfaces(); 
     for (int i = 0; i < interfaces.Length; i++) 
      if (base.TryGetValue(interfaces[i], out value)) 
       return true; 

     Type @base = key.BaseType; 
     if (@base != null && TryGetValue(@base, out value)) 
      return true; 

     return false; 
    } 
} 

注意,如果B类导出来自类A和接口IA和IB,并且为每个类型分配一个值,这是不明确的:应该返回A,IA还是IB的值?上面的实现选择它找到的第一个接口,并且只有在没有找到接口的情况下,才会查找基类。

我不知道这本词典的表现有多好。如果GetInterfaces()或BaseType属性很慢,它会使查找性能非常糟糕(只要您请求的确切类型不在字典中)。

相关问题