当运行"is"表达式时,结果返回false,但在检查时返回true。

16

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

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

这一切都很好,但是我注意到当我知道我有一个实现了IRichAdminCustomControl的对象时,表达式的求值结果为false。

好的,这就变得非常奇怪了。如果我在调试时检查代码,表达式的求值结果为true,但是如果我立即让代码运行并检查结果,则它的求值结果为false(我已经附上一个动画GIF以说明这一点)。

enter image description here

有没有人遇到过这样的奇怪情况,如果有,到底是什么原因造成的?

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


12
那个GIF图让我有一瞬间害怕了。 - pcnThird
4
好的。我的鼠标为什么会这样移动? - spender
6
你定义了多少个IRichAdminCustomControl接口?有没有可能Visual Studio选择了错误的接口? - Alexei Levenkov
3
我已经盯着这个 GIF 看了一会儿了... - Simon Whitehead
7
哈哈,我很高兴你们都喜欢我的gif。从现在开始我会确保每个问题中都会包含一个 :) - Iain Fraser
显示剩余12条评论
4个回答

7
如果您正在使用Visual Studio 2010 SP1,我发现了这个bug: 调试x64代码时变量值的错误报告 Microsoft在该页面上发布了一个解决方法:
您可以将所有项目设置为编译为x86,或创建一个中间初始化变量声明来确保调试器报告要检查的变量的正确值。
请尝试此解决方法:
bool isWhatWeWant = true;
isWhatWeWant &= (obj is IRichAdminCustomControl);
bool finalValue = isWhatWeWant; // this line should fix isWhatWeWant too in the debugger
return finalValue;

编辑:似乎VS2012在特定情况下也会遇到类似的问题。


该死!我对这个答案充满希望,似乎很有道理。不幸的是,没有成功 :( - Iain Fraser
我现在完全没有任何想法!:) 如果我有任何发现,我会回来的。如果您在此期间成功解决了问题,请告诉我们。 - Cosmin Vană
没问题,如果我找到解决方案,我会发布的。有趣的是,我尝试了 typeof(IRichAdminCustomControl).IsAssignableFrom(obj.GetType()); 这个方法一直返回 false,这是一个很大的线索。此外,关于加载自定义控件的方式,这个产品的工作方式也很有趣。我最终在我的 bin 中得到了一个 dll,但是这个 dll 也会从外部目录动态加载 - 我认为这可能是关键所在。如果我发现什么,我会告诉你的。 - Iain Fraser

2

我能想到两种可能性。第一种可能是你的接口名称足够通用,可能已经在命名空间中存在。尝试在is子句中完全限定接口。第二种可能是你可能正在作为构造函数的一部分运行代码,或者被构造函数间接调用。任何反射类似的操作都需要在我们确定应用程序已完全加载后执行。


2
所以我找到了答案。原因是我在不同的位置有两个dll文件的副本。一个在后端应用程序的bin目录中,另一个在被后端应用程序动态加载的共享外部目录中。
我需要解释一下:这个应用程序由两个应用程序同时运行组成,一个前端应用程序和一个后端应用程序。通常,您将“自定义控件”放入前端应用程序中。然后,这些控件会在应用程序启动时复制到一个对后端应用程序可访问的外部目录中。
在这种情况下,我的自定义控件库中有需要在后端应用程序中访问的逻辑 - 因此我必须引用它...结果导致后端应用程序对同一类有两个引用。哎呀!当你调试时当然会工作。
解决方案是将我的额外逻辑拆分到自己的项目中,并在后端应用程序中引用它。
我不会在这里“接受”我的答案,因为虽然它解决了我的具体问题,但解决方案对我正在处理的应用程序来说太具体化了,不太可能帮助其他人。

1
这种情况曾经发生在我身上,虽然我从未得出为什么会发生的结论,但我认为加载调试符号的PDB文件不同步。因此,通过“清理”解决方案,然后重新构建解决方案,这个奇怪的问题就消失了。

谢谢建议。是的,我的其中一位同事建议进行清理和重建 - 我很兴奋,因为我认为这一定就是答案!然而,它并没有起作用。但我认为解决方案很可能与您刚才提出的相关。 - Iain Fraser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接