我有一个代表外部物理测量设备的类。简化版如下所示:
public class Device {
public string Tag { get; set; }
public int Address { get; set; }
}
Tag
是用于识别设备的用户定义值。Address
是适配器用来与设备通信的值。如果两个实例Device
具有相同的Address
,则将使用相同的外部测量设备。
我想通过覆盖和实现来模仿代码中的这种行为(用于使用Contains
和之类的方法) :Distinct
Equals
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
了Equals
.
所以,我的问题是:我应该在实现中忽略该Tag
属性Equals
吗?这样做是否会使代码更难理解?有没有更好的方法来做我想做的事情?我需要该Tag
属性,因为通常用户不知道Address
,甚至不知道是否Device
有Address
( 在 App.config 文件中处理,并且用户将处理一个名为的接口,该接口IDevice
不有财产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();
}
}
}