繁体   English   中英

更简洁地表达C#泛型类型参数?

[英]Express C# generic type arguments more succinctly?

受启发

比较两个集合是否相等,无论它们中的项顺序如何

我创建了一个扩展方法来测试两个集合是否等效。 要使用扩展方法,我必须指定两个类型参数,如下所示:

IsEquivalentToTestHelper<ObservableCollection<string>, string>(first, second, true);

有没有一种方法可以实现扩展方法,以便只需要指定一个通用约束(例如ObservableCollection<string> )?

更新 :根据答案发布修改后的代码,作为对启发该问题的问题的补充回答

这是我的原始代码:

static public class EnumerableExtensions 
{
    static public bool IsEquivalentTo<E,T>(this E first, E second) where E : IEnumerable<T>
    {
        if ((first == null) != (second == null))
            return false;

        if (!object.ReferenceEquals(first, second) && (first != null))
        {
            if (first.Count() != second.Count())
                return false;

            if ((first.Count() != 0) && HaveMismatchedElement<E,T>(first, second))
                return false;
        }

        return true;
    }

    private static bool HaveMismatchedElement<E,T>(E first, E second) where E : IEnumerable<T>
    {
        int firstCount;
        int secondCount;

        var firstElementCounts = GetElementCounts<E,T>(first, out firstCount);
        var secondElementCounts = GetElementCounts<E,T>(second, out secondCount);

        if (firstCount != secondCount)
            return true;

        foreach (var kvp in firstElementCounts)
        {
            firstCount = kvp.Value;
            secondElementCounts.TryGetValue(kvp.Key, out secondCount);

            if (firstCount != secondCount)
                return true;
        }

        return false;
    }

    private static Dictionary<T, int> GetElementCounts<E,T>(E enumerable, out int nullCount) where E : IEnumerable<T>
    {
        var dictionary = new Dictionary<T, int>();
        nullCount = 0;

        foreach (T element in enumerable)
        {
            if (element == null)
            {
                nullCount++;
            }
            else
            {
                int num;
                dictionary.TryGetValue(element, out num);
                num++;
                dictionary[element] = num;
            }
        }

        return dictionary;
    }

    static private int GetHashCode<E,T>(IEnumerable<T> enumerable) where E : IEnumerable<T>
    {
        int hash = 17;

        foreach (T val in enumerable.OrderBy(x => x))
            hash = hash * 23 + val.GetHashCode();

        return hash;
    }
}
static public bool IsEquivalentTo<T>(this IEnumerable<T> first, IEnumerable<T> second) 

您可以删除第一个并保留第二个:

static public bool IsEquivalentTo<T>(this IEnumerable<T> first, IEnumerable<T> second)

您只需要用IEnumerable<T>替换每个E ,然后删除where语句即可。

例如:

static public bool IsEquivalentTo<T>(this IEnumerable<T> first, IEnumerable<T> second)

var firstElementCounts = GetElementCounts<IEnumerable<T>,T>(first, out firstCount);

static private int GetHashCode<T>(IEnumerable<T> enumerable)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM