如何泛化我的Dictionary <string,bool =“”>等价扩展方法?</string,>

时间:2009-02-11 05:51:28

标签: c# generics

为两个字典制作通用等价函数的最佳方法是什么,其键和值是值类型?

现在我有一个字典<字符串,bool&gt;,并创建了一个扩展方法(我认为)可以测试两个字典<字符串,bool&gt;之间的等效性。

我想让它更通用。我的第一个想法就是这样:

public static bool EquivalentTo<K, V>(this IDictionary<K, V> lhs, 
                                           IDictionary<K, V> rhs) 
        where K: struct 
        where V: struct
    { }

但是,这不起作用,因为字符串是不可变的引用类型,而不是值类型。

那么如何对字典<字符串的原始等价测试进行泛化,bool&gt; ?

2 个答案:

答案 0 :(得分:1)

为什么要首先将KV限制为值类型?我建议你删除约束。虽然字典有“有趣”的东西 - 两个字典碰巧有相同的条目,但使用不同的相等比较器相当于?遗憾的是,IDictionary<,>没有相等比较器属性,因此您可能需要提供等效方法。你需要考虑它在这里的含义是什么意思。

例如,两个带有不区分大小写的相等比较器的字典可能有{“FOO”,true}和{“foo”,true} - 在某种程度上它们是等价的,但在某种程度上它们不是。这取决于你想要使用等价关系的内容。

编辑:这是一个在大多数情况下应该没问题的例子,但是如果两个字典对待密钥的方式不同,可能会产生奇怪的结果:

public static bool EquivalentTo<TKey, TValue>(
     this IDictionary<TKey, TValue> first,
     IDictionary<TKey, TValue> second)
{
     return first.EquivalentTo(second, EqualityComparer<TValue>.Default);
}

public static bool EquivalentTo<TKey, TValue>(
     this IDictionary<TKey, TValue> first,
     IDictionary<TKey, TValue> second,
     IEqualityComparer<TValue> valueComparer)
{
    if (first == second)
    {
        return true;
    }
    if (first == null || second == null)
    {
        return false;
    }
    if (first.Count != second.Count)
    {
        return false;
    }
    foreach (var firstKeyValue in first)
    {
        TValue secondValue;
        if (!second.TryGetValue(firstKeyValue.Key, out secondValue) ||
            !valueComparer.Equals(firstKeyValue.Value, secondValue))
        {
            return false;
        }
    }
    return true;
}

未经测试,但请告诉我它是否符合您的要求......

答案 1 :(得分:0)

我想不出一种方法可以在一个构造中完成您正在寻找的东西。您可能有重载明确使用字符串而不是类型的模板参数,因此您最终会遇到3次重载:

public static bool EquivalentTo<string, V>(this IDictionary<string, V> lhs, 
                                                IDictionary<string, V> rhs) 
    where V: struct
{ }
public static bool EquivalentTo<K, string>(this IDictionary<K, string> lhs, 
                                                IDictionary<K, string> rhs) 
    where K: struct
{ }
public static bool EquivalentTo<K, V>(this IDictionary<K, V> lhs, 
                                           IDictionary<K, V> rhs) 
    where K: struct 
    where V: struct
{ }

我很确定这不是你想要的,但我没有更好的想法。