【问题标题】:Result of "is" expression returns false when run, but true when inspected"is" 表达式的结果在运行时返回 false,但在检查时返回 true
【发布时间】:2014-02-02 00:48:57
【问题描述】:

我有以下代码。 CustomControlHelper 通过反射生成对象的实例。在这个阶段,我们不知道我们正在处理什么类型的对象。我们确实知道它将是一个CustomControl,但我们不知道它是否实现了任何特定的接口,或者它是否扩展了任何其他类。下面的代码试图确定加载的控件是否实现了IRichAdminCustomControl接口。

Object obj = CustomControlHelper.GetControl(cc.Id, cc.ControlClass);            
if(obj != null)
{
    bool isWhatWeWant = (obj is IRichAdminCustomControl);
    return isWhatWeWant;
}

没关系,但我注意到,当我知道我有一个实现 IRichAdminCustomControl 的对象时,表达式的计算结果为 false。

好的,这就是它变得非常奇怪的地方。如果我在调试时检查代码,表达式的计算结果为真,但如果我立即让代码运行并检查结果,它的计算结果为假(我在下面附上了一个动画 gif 来说明)。

以前有没有人遇到过这样的怪事,如果有,到底是什么原因造成的?

顺便说一句,我相信我使用的产品使用 Spring.NET 在 CustomControlHelper 中提供依赖注入。

【问题讨论】:

  • 那张 GIF 图片吓到我一秒。
  • 是的。我的鼠标怎么这样动???
  • 你定义了多少个IRichAdminCustomControl接口? VS 有机会选错吗?
  • 我已经盯着这个 GIF 看了一段时间了...
  • 哈哈,很高兴你们都喜欢我的 gif。从现在开始,我会确保在每个问题中都包含一个 :)

标签: c# .net spring


【解决方案1】:

如果您使用的是 Visual Studio 2010 SP1,我遇到了这个错误:

Misreporting of variable values when debugging x64 code

该页面上有一个解决方法,由 Microsoft 发布:

您可以将所有项目设置为编译为 x86,或创建中间初始化变量声明以确保调试器报告正在检查的变量的正确值。

试试这个解决方法:

bool isWhatWeWant = true;
isWhatWeWant &= (obj is IRichAdminCustomControl);
bool finalValue = isWhatWeWant; // this line should fix isWhatWeWant too in the debugger
return finalValue;

编辑:似乎VS2012在特定条件下也遇到了类似的问题。

【讨论】:

  • 该死!我对这个答案充满希望。这似乎是有道理的。不幸的是,没有骰子:(
  • 我现在完全没有想法! :) 如果我找到任何东西,我会回来的。如果您在此期间设法修复它,请告诉我们。
  • 别担心,如果我找到解决方案,我会发布。有趣的是,我尝试了typeof (IRichAdminCustomControl).IsAssignableFrom(obj.GetType());,它始终返回false,所以这是一个很大的线索。此外,该产品在加载自定义控件方面的工作方式也很有趣。我最终在我的 bin 中得到了一个 dll,但 dll 也是从外部目录动态加载的——我认为这可能是关键。如果我发现了什么,我会告诉你的。
【解决方案2】:

我想到了两种可能性。首先是您的接口名称足够通用,以至于它可能已经在某个名称空间中。尝试完全限定 is 子句中的接口。第二种可能性是您可能将代码作为构造函数的一部分运行,或者被构造函数间接调用。任何反射之类的东西都需要在我们确定应用程序已完全加载后进行。

【讨论】:

    【解决方案3】:

    所以我找到了答案。这是因为我在不同位置有两个 dll 副本。我在后端应用程序的 bin 中有一份副本,在后端应用程序动态加载的共享外部目录中有一份。

    我应该解释一下;这个应用程序由两个串联运行的应用程序组成,一个前端应用程序和一个后端应用程序。通常,您将“自定义控件”放入前端应用程序中。然后在应用程序启动时将这些控件复制到后端应用程序可访问的外部目录。

    在这种情况下,我的自定义控件库中有需要在后端应用程序中访问的逻辑 - 所以我必须对其进行引用...最终后端应用程序有两个相同的引用班级。哦!当然,当您调试时,它会起作用。

    解决方案是将我的额外逻辑拆分到自己的项目中,并在后端应用程序中引用它。

    我不会在这里“接受”我自己的答案,因为虽然它解决了我的具体问题,但该解决方案对我正在使用的应用程序来说有点过于具体,不太可能帮助其他任何人。

    【讨论】:

      【解决方案4】:

      这发生在我身上一次,尽管我从未得出关于为什么会发生这种情况的结论,但我相信正在加载的 PDB 文件与调试符号不同步。因此,通过“清理”解决方案然后重建解决方案,这个奇怪的问题就消失了。

      【讨论】:

      • 感谢您的建议。是的,我的一位同事建议进行清洁和重建——我对此感到非常兴奋,因为我认为一定是这样!唉,它没有用。但我认为解决方案很可能与您刚才的建议有关。
      猜你喜欢
      • 1970-01-01
      • 2011-06-02
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 2019-03-29
      • 1970-01-01
      相关资源
      最近更新 更多