.net 类型字典?

.net 类型字典?,.net,.net,有人听说过使用类型作为键并支持继承的“类型字典”吗 在我的应用程序中,我希望有一个从类型到函数的字典,有点像这样: Dictionary<Type, Func<object, object>> Transformers; 普通字典的缺点是类型必须完全匹配。因此,如果我已经为IList编写了一个transformer,那么将其放入Transformers字典是没有用的,因为没有对象具有IList类型(只有T[],List等)。换句话说,如果obj是一个列表,则在普通字典中

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

在我的应用程序中,我希望有一个从类型到函数的字典,有点像这样:

Dictionary<Type, Func<object, object>> Transformers;
普通字典的缺点是类型必须完全匹配。因此,如果我已经为IList编写了一个transformer,那么将其放入Transformers字典是没有用的,因为没有对象具有IList类型(只有T[],List等)。换句话说,如果obj是一个列表,则在普通字典中查找不会找到IList的transformer


假设没有TypeDictionary这样的东西,如果不太难,我可以考虑写一个。你知道如何完成吗?

你应该能够使用一本字典和一个用来比较键的

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


该解决方案的唯一问题是,当存在多个匹配项时,您没有任何方法来指定要采用哪个匹配项。如果你需要这种灵活性和控制,我建议你考虑一下设计模式。每个转换器都可以是链中的一个链接,它负责确定是否可以将其应用于对象。如果没有,它将请求传递到下一个链接。链中变压器的顺序决定优先级。您失去了哈希表的速度,但由于多次查找,您还是失去了一些速度。

我发现字典设置程序与普通字典没有不同的语义,因此一种方法是使用具有专门查找功能的标准字典:

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;
    }
}
公共类类型字典:字典
{
公共新TValue此[类型键]
{
得到{
t价值;
if(TryGetValue(键,输出值))
返回值;
抛出newkeynotfoundexception(“未找到:+key.Name”);
}
}
public new bool TryGetValue(键入key,out TValue值)
{
if(基本TryGetValue(键,输出值))
返回true;
Type[]interfaces=key.GetInterfaces();
for(int i=0;i
请注意,如果类B派生自类a和接口IA和IB,并且为每种类型分配了一个值,那么它是不明确的:是否应返回a、IA或IB的值?上面的实现选择它找到的第一个接口,并且只有在没有找到接口的情况下,它才会查找基类


我不知道这本词典的性能有多好。如果GetInterfaces()或BaseType属性速度较慢,则会使查找性能非常差(只要您请求的确切类型不在字典中)

那不行。对于从a派生并实现IA和IB的类B,IEqualityComparer将返回哪个哈希代码?另外,请记住,词典应该能够同时保存
列表
IList
对象
的键。@Qwertie在这种情况下,如果词典中有多个类型的匹配项,词典将返回什么?它是否应该返回所有出现的情况,只返回最专门的情况,等等?请注意,问题只存在于接口的情况下(对于基类,很明显:返回最专门的可用类型)。我的TypeDictionary可以通过使用更确定的规则来改进:首先搜索基类,如果没有找到基类,则查找最专门的适用接口,例如,如果有IEnumerable和IList的处理程序,并且我们正在搜索
列表
,显然应该返回IList的处理程序,而不是IEnumerable。这将处理最常见(但不是所有)的歧义源。我不确定责任链设计模式在这种情况下是如何应用的。无论如何,我不喜欢这种模式,至少当链的链接可以由不同的人编写时不喜欢,因为我不相信链中的每个链接都记得调用链中的下一个处理程序。我稍微澄清了一下责任链。每个变压器都成为链中的一个环节。由您决定是让调用代码实现整个链接类,还是只传入一个函数和一个类型,由您自己的链接类在链中保存。顺便说一下,如果不存在歧义的问题,我认为Qwertie的建议更简单。
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;
    }
}