出现了一个奇怪的案例。两个对象的两个属性被转换为相同的基元类型,并且(看似)具有相同的值。但是,相等比较器返回false
。如果我们使用Equals
方法(或其他比较两个值的方法),那么我们会得到正确的结果。
更奇怪的是,实际上将演员表的结果放入一个新变量似乎也有效。
下面是一个非常简化的代码示例,并且 NOT 在复制和编译时会产生相同的结果。它仅用于说明问题发生的一般设置。
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;
}
我还更新了屏幕截图以包含更多屏幕。在屏幕截图中,上面的代码存在一些细微的差异,因为我们正在测试以查看正在发生的事情(例如尝试不同的强制转换或将转换结果分配给变量)。但问题的关键在那里。