“is”表达式的结果在运行时返回 false,但在检查时返回 true

问题描述 投票:0回答:5

我有以下代码。 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 中提供依赖注入。

c# .net spring
5个回答
7
投票

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

调试 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在特定条件下也遇到类似的问题。


2
投票

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


2
投票

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

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

在这种情况下,我的自定义控制库中有需要在后端应用程序中访问的逻辑 - 所以我必须引用它......最终后端应用程序对同一类有两个引用。噢!当然,当你调试时这会起作用。

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

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


1
投票

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


0
投票

就其价值而言,我只是在不同的环境中使用不同的解决方案遇到了这个问题。我在运行时加载程序集(主要来自单独的 DLL,这些 DLL 通过提供在我的“主”程序集中实现接口的类来扩展功能);一些核心功能是在我的“主”程序集中实现的(实现相同的接口)。

我最终再次加载我的“主”程序集(通过用于扩展的相同机制获取核心功能),并从中创建该类的实例;尽管接口类型看起来相同,但“is”测试失败了,它们位于不同的应用程序域中(我正在比较的那个是在我的“主”程序集中(在启动时加载),而我正在比较的那个是在我的“主”程序集的副本中) “主”程序集(在运行时加载)。

我的解决方案是检测我是否要再次加载我的“主”程序集,而不是加载它,只是返回已加载的实例。

© www.soinside.com 2019 - 2024. All rights reserved.