检查 OpenFileDialog.OpenFile 是否为空

Check if OpenFileDialog.OpenFile is null

我已经在 the msdn doc 中查看了这段代码:

Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
[...] // Some init
try
{
    if ((myStream = openFileDialog1.OpenFile()) != null)
    {
        using (myStream)
        {
            // Insert code to read the stream here.
        }
    }
}

但是 Resharper 温柔地告诉我,检查 null 是没有用的:

我应该相信 Resharper 还是微软?

这是 OpenFile().

的(大部分)源代码

try 块有可能抛出异常,而 return 的方法 Streamnull,所以我相信 MSDN文档。我不确定 ReSharper 为何提出该建议。

public Stream OpenFile()
{ 
    string filename = FileNamesInternal[0];

    if (filename == null || (filename.Length == 0))
        throw new ArgumentNullException("FileName");

    Stream s = null; 

    new FileIOPermission(FileIOPermissionAccess.Read, IntSecurity.UnsafeGetFullPath(filename)).Assert();
    try
    {
        s = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 
    }
    finally 
    { 
        CodeAccessPermission.RevertAssert();
    } 
    return s;
}

R# 在这方面是正确的,如果你反编译 class(见下面的代码),它的实现方式 永远不会 return null(它总是 return 是一个流或抛出异常):

public Stream OpenFile()
{
    IntSecurity.FileDialogOpenFile.Demand();
    string str = this.FileNamesInternal[0];

    if (str == null || str.Length == 0)
        throw new ArgumentNullException("FileName");

    new FileIOPermission(FileIOPermissionAccess.Read, IntSecurity.UnsafeGetFullPath(str)).Assert();

    try
    {
        return (Stream) new FileStream(str, FileMode.Open, FileAccess.Read, FileShare.Read);
    }
    finally
    {
        CodeAccessPermission.RevertAssert();
    }
}

也就是说:

  • 在该特定用例中添加空检查根本不会改变性能,因此您可以保留它。作为一般规则,在使用不属于您的函数之前检查其结果是否为 null 并不是一个坏习惯
  • 就像所有软件一样,R# 有时也会有错误(参见示例:Why does ReSharper think that "thread.Name == null" is always false?),所以不要盲目地听从它的所有建议:)
  • MSDN 示例有时写得不好,或者更糟,所以不要盲目 copy/paste 他们的所有示例 :)