C# C语言中两个结构的等价性#

C# C语言中两个结构的等价性#,c#,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<

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

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);
    }
公共结构系列
{
T[]X;
双[]Y;
公共系列(T[]x,双[]y)
{
X=X;
Y=Y;
}
公共覆盖布尔等于(对象对象对象)
{
返回obj为系列&&this==(系列)obj;
} 
公共静态布尔运算符==(系列s1,系列s2)
{
返回s1.X==s2.X&&s1.Y==s2.Y;
}
公共静态布尔运算符!=(系列s1,系列s2)
{
返回!(s1==s2);
}
这不行,我还缺什么

        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);
double[]xa={2,3};
double[]ya={1,2};
双[]xb={2,3};
双[]yb={1,2};
A系列=新系列(xa,ya);
B系列=新系列(xb,yb);
主张平等(A、B);

您正在比较数组引用,而不是它们的内容。
ya
yb
引用不同的数组。如果要检查数组的内容,必须明确地进行检查

恐怕我认为框架中没有任何东西可以为您做到这一点。不过,类似这样的东西应该可以:

public static bool ArraysEqual<T>(T[] first, T[] second)
{
    if (object.ReferenceEquals(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;
}
公共静态布尔数组相等(T[]第一,T[]第二)
{
if(object.ReferenceEquals(第一,第二))
{
返回true;
}
if(first==null | | second==null)
{
返回false;
}
if(first.Length!=second.Length)
{
返回false;
}
IEqualityComparer comparer=EqualityComparer.Default;
for(int i=0;i
顺便说一句,你的结构是可变的,因为数组内容可以在结构创建后更改。你真的需要这个结构吗

编辑:正如Nick在评论中提到的,您也应该重写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;
}
publicstaticintgethashcode(T[]数组)
{
if(数组==null)
{
返回0;
}
IEqualityComparer comparer=EqualityComparer.Default;
int hash=17;
foreach(数组中的T项)
{
hash=hash*31+comparer.GetHashCode(项);
}
返回散列;
}

部分
s1.Y==s2.Y
测试它们是否是对同一数组实例的两个引用,而不是内容是否相等。因此,尽管有标题,这个问题实际上是关于数组(-reference)之间的相等


一些额外的建议:由于您将
Serie
重载为不可变,并且由于嵌入的数组,我将使其成为类而不是结构。

调用
=
对数组执行引用相等-它们不会比较元素的内容。这基本上意味着
a1==a2
只会如果是完全相同的实例,则返回true-我认为这不是您想要的

您需要修改
操作符==
来压缩
x
数组的内容,而不是它的参考值

如果您使用的是.NET 3.5(带链接),您可以执行以下操作:

public static bool operator ==(Serie<T> s1, Serie<T> s2)
{
    return ((s1.X == null && s2.X == null) || s1.X.SequenceEquals( s2.X )) 
           && s1.Y == s2.Y;
}
公共静态布尔运算符==(序列s1,序列s2)
{
返回((s1.X==null&&s2.X==null)| | s1.X.SequenceEquals(s2.X))
&&s1.Y==s2.Y;
}
如果需要进行深度比较(超出参考范围),可以为T类型提供自定义的
IEqualityComparer


您可能还应该考虑为您的Stutt实现<代码> IEQuabtE//>接口。这将帮助您的代码更好地与LINQ和执行对象比较的.NETFramework的其他部分一起工作。

您应该比较等式逻辑中的数组的内容……/P> 此外,建议您在结构上实现接口,因为这在某些情况下可以防止装箱/取消装箱问题。


您可以为结构创建私有访问器,并使用
CollectionAssert

[TestMethod()]
public void SerieConstructorTest()
{
    double[] xa = { 2, 3 };
    double[] ya = { 1, 2 };
    double[] xb = { 2, 3 };
    double[] yb = { 1, 2 };
    var A = new Serie_Accessor<double>(xa, ya);
    var B = new Serie_Accessor<double>(xb, yb);
    CollectionAssert.AreEqual(A.X, B.X);
    CollectionAssert.AreEqual(A.Y, B.Y);
}
[TestMethod()]
public void SerieConstructorTest()
{
双[]xa={2,3};
double[]ya={1,2};
双[]xb={2,3};
双[]yb={1,2};
var A=新系列存取器(xa,ya);
var B=新的系列存取器(xb,yb);
集合资产等于(A.X,B.X);
集合资产相等(A.Y,B.Y);
}
这段代码运行良好

参考资料:

恐怕我认为框架中没有任何东西可以为您做到这一点

在4.0中,有:

StructuralComparisons.StructuralEqualityComparer.Equals(firstArray, secondArray);

使用LINQ的SequenceEqual()扩展方法。它可以比较数组内容。可能,但我倾向于选择清晰而不是性能,除非存在衡量性能的问题。出于好奇,是什么让你认为
SequenceEquals
效率低下?+1我想补充一点,在重写Equals时需要重写GetHashCode,因此你需要散列数组(或者使用非常糟糕的哈希代码,比如总是返回常量)@LBushkin:除非它在某个地方针对数组进行了实际优化,否则它不会有最有效的路径。数组可以进行大量优化。我同意总体上更倾向于简单,但这是一种有用的实用方法,只需编写一次,然后在很多地方使用。@Nick:GetHashCode的优点;我会将其添加到回答。哦,把我的声音添加到,这真的不应该是一个结构相关的帖子-“这是一个很好的答案,但是如果它自己站着,而不引用另一个答案会更好。