繁体   English   中英

看似相同的原始值不相等

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM