C#中两个结构的相等性

Fre*_*ric 8 c#

我寻找这个结构的两个实例之间的相等.

public struct Serie<T>
{
    T[]         X; 
    double[]    Y;

    public Serie(T[] x, double[] y)
    {
        X = x;
        Y = y;
    }

    public override bool Equals(object obj)
    {
        return obj is Serie<T> && this == (Serie<T>)obj;
    } 
    public static bool operator ==(Serie<T> s1, Serie<T> s2)
    {
        return s1.X == s2.X && s1.Y == s2.Y;
    }
    public static bool operator !=(Serie<T> s1, Serie<T> s2)
    {
        return !(s1 == s2);
    }
Run Code Online (Sandbox Code Playgroud)

这不起作用.我错过了什么?

        double[] xa = { 2, 3 };
        double[] ya = { 1, 2 };
        double[] xb = { 2, 3 };
        double[] yb = { 1, 2 };
        Serie<double> A = new Serie<double>(xa, ya);
        Serie<double> B = new Serie<double>(xb, yb);
        Assert.AreEqual(A, B);
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 19

您正在比较数组引用而不是它们的内容.yayb参考不同的数组.如果要检查数组的内容,则必须明确地执行此操作.

我不认为框架中有任何内容可以帮助你做到这一点,我担心.这样的东西应该工作:

public static bool ArraysEqual<T>(T[] first, T[] second)
{
    if (first == second)
    {
        return true;
    }
    if (first == null || second == null)
    {
        return false;
    }
    if (first.Length != second.Length)
    {
        return false;
    }
    IEqualityComparer comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < first.Length; i++)
    {
        if (!comparer.Equals(first[i], second[i]))
        {
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你的结构有点可变,因为在创建结构之后可以更改数组内容.你真的需要这个结构吗?

编辑:正如尼克在评论中提到的那样,你也应该覆盖GetHashCode.同样,您需要从数组中获取内容(同样,如果数组之后发生更改,这将导致问题).类似的实用方法:

public static int GetHashCode<T>(T[] array)
{
    if (array == null)
    {
        return 0;
    }
    IEqualityComparer comparer = EqualityComparer<T>.Default;
    int hash = 17;
    foreach (T item in array)
    {
        hash = hash * 31 + comparer.GetHashCode(item);
    }
    return hash;
}
Run Code Online (Sandbox Code Playgroud)

  • 使用LINQ的SequenceEqual()扩展方法.它可以比较数组内容. (11认同)
  • +1我想补充一点,当覆盖Equals时需要覆盖GetHashCode,因此你需要对数组进行哈希处理(或者使用非常糟糕的哈希代码,比如总是返回一个常量). (5认同)
  • 可能,但我倾向于清晰度而不是性能,除非存在测量的性能问题.出于好奇,是什么让你相信`SequenceEquals`效率低下? (2认同)
  • @LBushkin:除非它在某个地方实际上已经*优化*,否则它将无法获得最有效的路径.数组可以进行相当大的优化.我同意在一般情况下更喜欢简单,但这是一种有用的实用方法,可以编写一次然后在很多地方使用.@Nick:关于GetHashCode的好点; 将添加到答案. (2认同)
  • 哦,加上我的声音,这*真的*不应该是一个结构. (2认同)

Seb*_*ich 6

我不认为框架中有任何内容可以帮助你做到这一点,我担心

在4.0中,有:

StructuralComparisons.StructuralEqualityComparer.Equals(firstArray, secondArray);
Run Code Online (Sandbox Code Playgroud)


Fre*_*els 5

您应该在Equality逻辑中比较Array的内容......

此外,建议您IEquatable<T>在结构上实现接口,因为这可以防止在某些情况下出现装箱/拆箱问题. http://blogs.msdn.com/jaredpar/archive/2009/01/15/if-you-implement-iequatable-t-you-still-must-override-object-s-equals-and-gethashcode.aspx