有没有人听说过使用类型作为键并支持继承的“类型字典”?
在我的应用程序中,我希望有一个从类型到函数的字典,有点像这样:
Dictionary<Type, Func<object, object>> Transformers;这个想法是,它将被用来以某种方式根据对象的类型来转换对象:
// Transform an object 'obj'
object result = Transformers[obj.GetType()](obj)普通字典的缺点是类型必须完全匹配。因此,如果我为IList编写了一个转换器,那么将它放入Transformers字典中是没有用的,因为没有对象具有IList类型(只有T[]、List等)。换句话说,如果obj是一个列表,那么通过在普通字典中查找将不会找到IList的转换器。
假设没有TypeDictionary这样的东西,如果不是太难的话,我可能会考虑写一个。你有什么想法可以做到吗?
发布于 2009-12-05 02:07:17
您应该能够使用带有使用Type.IsAssignableFrom比较键的custom comparer的字典。
更新:正如Qwertie指出的那样,这是不起作用的,因为您不能基于类型、其接口和祖先类实现可重复的哈希代码计算。His answer通过重复查找类型、接口和祖先类的哈希表,直到找到匹配为止,提供了一种可能的解决方案。
该解决方案的唯一问题是,当有多个匹配时,您无法指定采用哪个匹配。如果您需要这种灵活性和可控性,我建议您考虑chain-of-responsibility设计模式。每个转换器都可以是链中的一个环节,它负责确定它是否可以应用于对象。如果不是,它将请求传递到下一个链接。链中转换器的顺序决定了优先级。你失去了哈希表的速度,但由于多次查找,你还是失去了一些速度。
发布于 2009-12-05 02:41:49
在我看来,字典设置器与普通字典没有不同的语义,因此一种方法是使用具有专门查找的标准字典:
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属性速度很慢,它将使查找性能变得非常糟糕(只要您请求的确切类型不在字典中)。
https://stackoverflow.com/questions/1848627
复制相似问题