【问题标题】:Entity Framework object is not null but `== null` returns true实体框架对象不为 null 但 `== null` 返回 true
【发布时间】:2014-06-24 18:11:44
【问题描述】:

我的代码:

var x = myEntities.MyTable
                  .Include("MyOtherTable")
                  .Include("MyOtherTable.YetAnotherTable")
                  .SingleOrDefault(c => c.Name == someName);

这会正确返回我可以在 Visual Studio 中以智能感知方式查看的对象。

下一行是:

if (x == null)
{
}

但是,此语句返回 true 并且 {} 中的代码会执行。这是什么原因造成的?

编辑:

在空检查上方添加了这一行:

var someName = x.Name;

这段代码完美运行,someName 变成了 string,其中包含对象的名称。

== null 仍然返回 true。

IDE 截图:

编辑:函数中的代码似乎可以工作:

    public void bibble(MyObjectType s)
    {
        if (s == null)
        {

            throw new Exception();
        }
    }
--
    string someName = testVariable.Name;

    this.bibble(testVariable); // Works without exception

    if (testVariable == null)
    {
        // Still throws an exception
        throw new Exception();
    }

现在它不会在其他方法中评估为 true,但在同一变量的 main 方法中评估。好诡异。

编辑:这是本节的 IL:

  IL_0037:  callvirt   instance string [MyLibrary]MyLibrary.MyCompany.MyObjectType::get_Name()
  IL_003c:  stloc.3
  IL_003d:  ldarg.0
  IL_003e:  ldloc.2
  IL_003f:  call       instance void MyOtherLibrary.ThisClass::bibble(class [MyLibrary]MyLibrary.MyCompany.MyObjectType)
  IL_0044:  nop
  IL_0045:  ldloc.2
  IL_0046:  ldnull
  IL_0047:  ceq
  IL_0049:  ldc.i4.0
  IL_004a:  ceq
  IL_004c:  stloc.s    CS$4$0001
  IL_004e:  ldloc.s    CS$4$0001
  IL_0050:  brtrue.s   IL_0059
  IL_0052:  nop
  IL_0053:  newobj     instance void [mscorlib]System.Exception::.ctor()
  IL_0058:  throw

编辑:更奇怪的是:

var myEFObjectIsNull = testVariable == null;

// Intellisense shows this value as being FALSE.

if (myEFObjectIsNull)
{
    // This code is ran. What.
    throw FaultManager.GetFault();
}

【问题讨论】:

  • 更新问题。太奇怪了!
  • 你确定if后面没有分号吗?
  • @celerno 会抛出编译器错误,除非 xbool
  • 在这一点上,消除了明显的问题,我倾向于认为“编译器错误”(它偶尔会发生)。您能否尝试将var x = ... 之后的所有内容拉到一个单独的方法中,即var x = ...; AnotherMethod(x);,在AnotherMethod 中使用您的if(x==null) 等?
  • @SLC 如果您仍然可以通过将代码移回原样来重现它,我会对失败代码的 IL 非常感兴趣。如果我们能证明它是一个编译器错误,我们应该确保它被记录下来。你熟悉提取 IL 吗?

标签: c# entity-framework


【解决方案1】:

如果您添加了自定义的 == 运算符重载,并且把它弄得一团糟,就会发生这种情况。重载将更喜欢==(MyTable,MyTable) 重载,并且在与null 进行比较时会选择它:

static class Program {
    static void Main() {
        Foo x = new Foo();
        if(x==null) {
            System.Console.WriteLine("Eek");
        }
    }
}

public class Foo {
    public static bool operator ==(Foo x,Foo y) {
        return true; // or something more subtle...
    }

    public static bool operator !=(Foo x, Foo y) {
        return !(x==y);
    }
}

【讨论】:

  • 有道理,但我没有这样做。也许 EF 内置了某种错误或奇怪的功能导致了这种情况?
  • @SLC 简单的查找方法:将其更改为:if(((object)x)==null) - 如果它工作正常,那么问题几乎可以肯定是运算符过载。您也可以将插入符号放在== 上,然后按F12,IIRC。这会将您带到它打算使用的运算符定义。
  • 你说得有道理,但他在某个地方有这个代码听起来很罕见。
  • @celerno 我愿意接受其他可能导致==null 报告错误的建议;我知道这个可以做到。
  • 上面的比较结果也是true,它执行大括号内的代码。
猜你喜欢
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
相关资源
最近更新 更多