使用 = = 比较两个结构体

我试图比较 C # 中使用 equals (= =)的两个 struct,我的 struct 如下:

public struct CisSettings : IEquatable<CisSettings>
{
public int Gain { get; private set; }
public int Offset { get; private set; }
public int Bright { get; private set; }
public int Contrast { get; private set; }


public CisSettings(int gain, int offset, int bright, int contrast) : this()
{
Gain = gain;
Offset = offset;
Bright = bright;
Contrast = contrast;
}


public bool Equals(CisSettings other)
{
return Equals(other, this);
}


public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}


var objectToCompareWith = (CisSettings) obj;


return objectToCompareWith.Bright == Bright && objectToCompareWith.Contrast == Contrast &&
objectToCompareWith.Gain == Gain && objectToCompareWith.Offset == Offset;


}


public override int GetHashCode()
{
var calculation = Gain + Offset + Bright + Contrast;
return calculation.GetHashCode();
}
}

我尝试将 struct 作为类中的一个属性,并且想要检查 struct 是否等于我试图赋值给它的值,然后继续执行操作,所以我并没有指示属性在没有改变的情况下发生了改变,像这样:

public CisSettings TopCisSettings
{
get { return _topCisSettings; }
set
{
if (_topCisSettings == value)
{
return;
}
_topCisSettings = value;
OnPropertyChanged("TopCisSettings");
}
}

然而,在检查相等性的那一行,我得到了这个错误:

运算符“ = =”不能应用于“ CisSettings”类型的操作数和 “ CisSettings”

我不明白为什么会发生这种事,谁能给我指个正确的方向?

74482 次浏览

您需要重载 ==!=操作符。请将以下内容添加到 struct:

public static bool operator ==(CisSettings c1, CisSettings c2)
{
return c1.Equals(c2);
}


public static bool operator !=(CisSettings c1, CisSettings c2)
{
return !c1.Equals(c2);
}

重写 .Equals()方法时,==操作符将自动重载 没有

参见 重写等式()和运算符 = = 的准则CA1815: 在值类型上重写等于和运算符等于

你没有 明确地实施等式运算符,所以 ==不是专门为类型定义的。

你应该像这样让你的操作员超载:

public static bool operator ==(CisSettings a, CisSettings b)
{
return a.Equals(b);
}

您需要显式地覆盖 Operator = = 。

public static bool operator ==(CisSettings x, CisSettings y)
{
return x.Equals(y);
}

顺便说一下,最好将比较代码放在 public bool Equals(CisSettings other)中,让 bool Equals(object obj)调用 bool Equals(CisSettings other),这样就可以避免不必要的类型检查,从而获得一些性能。

必须重载“ = =”运算符,但也要重载“ ! =”运算符。(看看这张纸条)

对于重载操作符,看这一页

创建一个方法并将两个 stuct obj 作为参数逐个进行比较

public Save ReturnGreater(Save online,Save local)
{
Save DataToSave = new Save();
DataToSave.Score = local.Score < online.Score ? online.Score : local.Score;
DataToSave.UnlockGuns = local.UnlockGuns < online.UnlockGuns ? online.UnlockGuns : local.UnlockGuns;
DataToSave.UnlockLevels = local.UnlockLevels < online.UnlockLevels ? online.UnlockLevels : local.UnlockLevels;
DataToSave.TotalLevels = local.TotalLevels;
DataToSave.RemoveAds = local.RemoveAds;
return DataToSave;
}

您还可以使用 Record 类型,因为 C # v9和[ Record struct ]值类型 从 C # v10开始,为了避免编写大量的重复代码 毫无意义

更多细节请点击这里查看 Microsoft 文档:

等式运算符(C # 引用)

在 C # 9.0及更高版本中可用,记录类型支持 = = 和! = 默认情况下提供值相等语义的运算符, 当两个记录操作数都为空或 所有字段和自动实现属性的对应值是 平等。

public class RecordTypesEquality
{
public record Point(int X, int Y, string Name);
public record TaggedNumber(int Number, List<string> Tags);


public static void Main()
{
var p1 = new Point(2, 3, "A");
var p2 = new Point(1, 3, "B");
var p3 = new Point(2, 3, "A");


Console.WriteLine(p1 == p2);  // output: False
Console.WriteLine(p1 == p3);  // output: True


var n1 = new TaggedNumber(2, new List<string>() { "A" });
var n2 = new TaggedNumber(2, new List<string>() { "A" });
Console.WriteLine(n1 == n2);  // output: False
}
}