[英]Seemingly identical primitive values aren't equal
一个奇怪的案例突然出现了。 两个对象的两个属性被转换为相同的基元类型,并且(看似)具有相同的值。 但是,相等比较器返回false
。 如果我们使用Equals
方法(或比较这两个值的其他方法),那么我们得到正确的结果。
更奇怪的是,实际上将演员的结果放入一个新的变量似乎也有效。
下面是一个非常简化的代码示例,并且在复制和编译时不会产生相同的结果。 它仅用于说明问题发生的一般设置。
class Program
{
static void Main(string[] args)
{
var v1 = new Object1 { SomeValue = (short)-1d };
var invalidResult = (int)v1.SomeValue == (int)SomeEnum.Value1; //for some reason this returns false
var validResult = ((int)v1.SomeValue).CompareTo((int)SomeEnum.Value1) == 0; //this works
var extraValidResult = ((int)v1.SomeValue).Equals((int)SomeEnum.Value1);
var cast1 = (int)v1.SomeValue;
var cast2 = (int)SomeEnum.Value1;
var otherValidResult = cast1 == cast2; //this also works
}
}
public class Object1
{
public short SomeValue { get; set; }
}
public enum SomeEnum : short
{
Value1 = -1,
Value2 = 0,
Value3 = 1
}
这是VS观察窗口的屏幕截图,作为我们所看到的内容的证明:
我知道有时VS可以在“监视”窗口中显示无效值,但是效果并不局限于该窗口,并且if
在我们的某个测试中它不应该检查,则实际上会失败。 AFAIK代码中没有任何诡计(如重写==
或Equals
)。
这可能发生什么?
(我们显然使用CompareTo
方法“修复”了这个问题,但是我们仍然在想知道究竟发生了什么......)
编辑:
我意识到上面的代码示例......有点无用。 但是,发布有问题的实际代码可能会非常困难; 有很多。 最后,一些对象的“实时”值从SQL服务器(使用实体框架)填充,这进一步使代码共享变得复杂。 我很乐意尝试回答任何其他问题以尝试缩小问题范围,但遗憾的是,不可能共享完整代码(特定的代码块可能,但由于显而易见的原因无法编译) 。 提供示例代码以显示问题有多奇怪。
编辑2:
抱歉耽搁了。 这是有问题的特定方法:
public bool IsLocalizationBlockedByMagPElem(int localizationId)
{
IEnumerable<MagPElem> magPElems = MagPElemRepository.GetByLocalizationIdAndStatusesOrderedByIdDescThenSubLpAsc(localizationId, DocumentStatus.InBuffer, DocumentStatus.InBufferReedition);
if (magPElems.Count() != 0)
{
var magPElem = magPElems.First();
//this commented out code did not return the expected value due to the strange comparison issue
//return (magPElem.MaP_GIDTyp == (int)ExternalSystemType.PM_GIDTyp || (magPElem.MaP_GIDTyp == (int)ExternalSystemType.MP_GIDTyp && magPElem.MaP_SubGIDLp == (short)LocalizationDirection.Destination));
//to avoid the issue CompareTo is being used, but Equals would work just as well
return (magPElem.MaP_GIDTyp == (int)ExternalSystemType.PM_GIDTyp || (magPElem.MaP_GIDTyp == (int)ExternalSystemType.MP_GIDTyp && magPElem.MaP_SubGIDLp.CompareTo((short)LocalizationDirection.Destination) == 0));
}
return false;
}
我还更新了屏幕截图,以包含更多屏幕。 在屏幕截图中,上面的代码存在一些细微的差异,因为我们正在测试以查看正在发生的事情(例如尝试不同的强制转换或将转换结果分配给变量)。 但问题的关键在那里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.