【问题标题】:Warning as Error: Possible unintended reference comparison when upgrading from .Net 3.5 to .Net 4.5警告为错误:从 .Net 3.5 升级到 .Net 4.5 时可能出现意外的参考比较
【发布时间】:2015-03-26 02:59:58
【问题描述】:

目前我正在将 WPF 应用程序从 .Net Framework 3.5 迁移到 .Net Framework 4.5。在 .Net Framework 升级之后,应用程序现在将编译为 64 位而不是 32 位。编译应用程序时出现以下错误:

错误警告:可能是意外的参考比较;要进行值比较,请将左侧类型转换为“System.Type”

我的问题是:为什么现在我已经升级到 .Net 4.5 而之前从未在 .Net 3.5 上出现此错误? 我没有对项目的构建属性进行任何更改,两者都将设置Treat warnings as errors 设置为All。下面是产生错误的代码,我添加了一些关于我所做更改的 cmets,未注释的部分在 .Net 4.5 下编译。

private void FoldersListBoxMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    // Get typed sender
    ListBox typedSender = sender as ListBox;
    if (typedSender != null)
    {
        // Check if an item was double clicked
        //The line below worked in .Net 3.5, but not in .Net 4.5
        //if ((typedSender.SelectedItem != null) && (typedSender.InputHitTest(e.GetPosition(typedSender)) != typedSender.GetType()))
        //And this is the line that I have changed (I added GetType()!).
        if ((typedSender.SelectedItem != null) && (typedSender.InputHitTest(e.GetPosition(typedSender)).GetType() != typedSender.GetType()))
        {
            // Yes, set the new path
            SelectedPath = typedSender.SelectedValue as string;
        }
    }
}

编辑:当此代码添加到应用程序时,我已经查找过,但无法找到它,因为 Subversion 存储库只能追溯到 6 年前。

【问题讨论】:

  • 你能解释一下这个条件在检查什么(如你所想?)。 InputHitTest 返回IInputElement,与typeof(ListBox) 比较背后的逻辑是什么?要双重确保? =D
  • 此错误可用since 2003(我假设这甚至来自以前的 c-sharp 编译器)。你确定你只是没有以某种方式忽略它吗?
  • @Sinatr:我的猜测是最初的程序员正在检查用户是否真的双击了 ListBox 中的项目,而不是滚动条。

标签: c# reference .net-3.5 comparison .net-4.5


【解决方案1】:

基本上,您之前的代码已损坏。你说它有效,但我看不出这个条件永远是错误的。我怀疑编译器现在比以前更聪明。条件是:

typedSender.InputHitTest(e.GetPosition(typedSender)) != typedSender.GetType()

现在InputHitTest 返回一个IInputElement 类型的值。所以条件(忽略第一部分)可以改写为:

IInputElement element = typedSender.InputHitTest(e.GetPosition(typedSender));
Type type = typedSender.GetType();
if (element != type)
{
    ...
}

两个引用可能相等的唯一方式是,如果它们都是null,并且typedSender.GetType() 将永远不会返回null,因此该条件毫无意义。

您现在比较作为命中测试结果的输入元素是否与typedSender 的类型相同,这至少是有道理的 - 尽管它不会检查它typedSender

值得注意的是documentation for InputHitTest包括:

此方法通常不会从您的应用程序代码中调用。仅当您打算重新实现大量已经存在的低级输入功能(例如重新创建鼠标设备逻辑)时,才适合调用此方法。

确定要调用它吗?

【讨论】:

  • 大胆猜测:这是某人的签名(不影响功能、难以检测且可用于捕获源盗版的东西)。
  • @Sinatr:代码已经超过 6 年了,无法追踪是谁编写的,但从应用程序的其余部分来看,我会说这只是一个错误,而不是一个狡猾的计划捕捉源海盗。
  • 所以,代码一开始就被破坏了,现在我已经“修复”了它,但这意味着应用程序的响应将与以前不同......此外,我不是确定此代码应该解决什么问题。那么,我确定要调用此代码吗?不,它认为我将删除它并在 cmets 中添加指向此答案的链接。
  • @GeertImmerzeel:要恢复原始行为,只需完全消除条件即可。条件总是评估为true,因为引用总是不同的。
  • @JonSkeet:那是我打算做的。
猜你喜欢
  • 2018-02-25
  • 1970-01-01
  • 2023-01-29
  • 2013-07-22
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多