gpt4 book ai didi

c# - 以可变类型实现 IEquatable

转载 作者:行者123 更新时间:2023-11-30 13:49:31 25 4
gpt4 key购买 nike

我有一个代表外部物理测量设备的类。简化版本如下所示:

public class Device {
public string Tag { get; set; }
public int Address { get; set; }
}

Tag是用于识别设备的用户定义值。 Address是适配器用来与设备通信的值。如果 Device 的两个实例有相同的Address , 然后将使用相同的外部测量设备。

我想通过覆盖 Contains 来模仿代码中的这种行为(使用 DistinctEquals 等方法)并实现 IEquatable<T> :

public class Device : IEquatable<Device> {
public string Tag { get; set; }
public int Address { get; set; }

public override bool Equals(object obj) {
return Equals(obj as Device);
}
public bool Equals(Device other) {
if (null == other) return false;
if (ReferenceEquals(this, other)) return true;
return Address.Equals(other.Address);
}
}

如您所见,我忽略了 Tag属性(property)在执行Equals .

所以,我的问题是: 我应该忽略 Tag 吗?属性(property)在执行Equals ?这样做会使代码更难理解吗?有没有更好的方法来做我想做的事情?我需要 Tag属性,因为用户通常不知道 Address ,甚至是否 Device有一个 Address (这是在 App.config 文件中处理的,用户将处理一个名为 IDevice 的接口(interface),它没有 Address 属性)。

更新:

感谢大家的回复。

所以,我想我应该使用自定义 IEqualityComparer .如果我的真实代码看起来更像这样,您是否有关于如何执行此操作的任何指导?

public interface IDevice {
string Tag { get; set; }
double TakeMeasurement();
}
internal class Device : IDevice {
public string Tag { get; set; }
public int Address { get; set; }
public double TakeMeasurement() {
// Take a measurement at the device's address...
}
}

我应该检查我的 IEqualityComparer 中的设备类型吗? ?

public class DeviceEqualityComparer : IEqualityComparer<IDevice> {
public bool Equals(IDevice x, IDevice y) {
Contract.Requires(x != null);
Contract.Requires(y != null);
if ((x is Device) && (y is Device)) {
return x.Address.Equals(y.Address);
}
else {
return x.Equals(y);
}
}

public int GetHashCode(IDevice obj) {
Contract.Requires(obj != null);
if (obj is Device) {
return obj.Address.GetHashCode();
}
else {
return obj.GetHashCode();
}
}
}

最佳答案

首先你忘了重写GetHashCode() ,所以您的代码已损坏。

IMO 你应该覆盖 Equals仅当两个对象对于所有目的都是等价的。和不同的对象Tag出于某些目的,它们似乎有所不同。

我不会覆盖 Equals在所有这些对象上。我宁愿实现一个自定义比较器 IEqualityComparer<T>并在适当的地方使用它。大多数具有相等概念的方法都采用 IEqualityComparer<T>。作为可选参数。

我不会禁止 null参数,但要处理它们。我还为引用平等添加了早出。

public class DeviceByAddressEqualityComparer : IEqualityComparer<IDevice> {
public bool Equals(IDevice x, IDevice y) {
if(x==y)
return true;
if(x==null||y==null)
return false;
return x.Address.Equals(y.Address);
}

public int GetHashCode(IDevice obj) {
if(obj == null)
return 0;
else
return obj.Address.GetHashCode();
}
}

如果要检查类型,取决于上下文。当覆盖 Equals我通常检查是否 x.GetType()==y.GetType() ,但由于您在这里使用了一个特殊用途的比较器,它故意忽略了对象的一部分,所以我可能不会将类型作为标识的一部分。

关于c# - 以可变类型实现 IEquatable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9265269/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com