4

我在 WPF 应用程序中编写了一些代码,如下所示:

var dialog = new OpenFileDialog { Filter = this.FileExtensionFilter };
var dialogResult = dialog.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value)
{
    ... Process result of dialog ...
}

一切都很好,我想,但是 ReSharper 在检查时提出了一个警告dialogResult.HasValue,“表达式总是正确的”。

第一个问题是 ReSharper 是如何知道 dialogResult 总是有结果的——它一定已经深入到Microsoft.Win32.OpenFileDialog类的反编译代码中并观察到它永远不会返回 null。要么,要么只是专门针对此类的硬编码警告。

其次,仅仅假设结果永远不会为空似乎不是一个好习惯。如果 Microsoft 发布了可以使用空值的库的未来版本怎么办?关于此事的文档说:“在当前的实现中,派生类(OpenFileDialog 和 SaveFileDialog)只会返回 true 或 false”,这确实意味着这不是我们可以永远依赖的永久安排。

关于我是否过于谨慎,是否应该像 ReSharper 建议的那样删除这条线有什么想法吗?

4

2 回答 2

3

看起来确实很奇怪。MSDN 规范声明它将返回 true 或 false,但 Nullable 仍然必须有原因。

我绝对同意你的看法,假设下面的实现是不好的做法。我会根据接口进行编码,所以在这种情况下,我认为检查 HasValue 是正确的方法。

Re-sharper 是如何知道的?恐怕我无法回答这个问题。这不是我使用的东西,他们可能已经对其进行了硬编码。

您可能对此感兴趣:Microsoft.Win32.OpenFileDialog.ShowDialog() 何时返回 null?

似乎存在 null 可能性的原因是因为这是用户关闭对话框之前的结果。

于 2013-10-29T11:09:22.180 回答
3

它是硬编码的。

如果您查看 Program Files 中的 ReSharper 目录,您会看到许多名称中带有Nullness.Gen的 XML 文件,这些文件包含有关特定元素是否为空的规则,这些用于显示警告,例如正如您所看到的那样,它们将无法正常显示。

如果您在Bin\ExternalAnnotations.NETFramework\System.Windows中找到2.0.5.0.Nullness.Gen.xml文件,您将在大约一半的位置找到以下条目:

<member name="M:System.Windows.Controls.OpenFileDialog.ShowDialog">
    <attribute ctor="M:JetBrains.Annotations.NotNullAttribute.#ctor" />
</member>

然后,您可以查看bin目录中的JetBrains.Annotations以查看NotNullAttribute的定义:

 <member name="T:JetBrains.Annotations.NotNullAttribute">
     <summary>
     Indicates that the value of the marked element could never be <c>null</c>
     </summary>
     <example><code>
     [NotNull] public object Foo() {
       return null; // Warning: Possible 'null' assignment
     }
     </code></example>
 </member>
于 2013-10-29T13:19:52.207 回答