检查 OpenFileDialog.OpenFile 是否为空。

4

我已经阅读了 msdn文档 中的此代码:

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是无用的:

enter image description here

我应该信任Resharper还是Microsoft?


1
永远相信开发者,Resharper只是一个代码“提示器”。 - James
@James 这次不行... - Thomas Ayoub
是的,在这种情况下,Resharper是正确的(顺便说一句,我从未说过它是错误的)。然而,我坚持我的观点,始终相信开发人员胜过第三方工具。有什么能阻止开发人员在幕后更改此方法的行为呢?最终,你那里的代码很好,虽然不必要,但没问题 - 你甚至可能会发现编译器足够聪明,可以将其删除 :) - James
2个回答

4
这里是OpenFile()方法的(大部分)源代码。

try块中可能会抛出异常,并且该方法返回一个值为nullStream对象,因此我建议您相信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;
}

@Thomas 这绝对是一个很棒的资源。 - Grant Winney
没有异常则没有返回值。返回的Stream对象绝不会为null - Hans Passant
@Hans,finally块中的代码是否会阻止return s执行并返回null - Grant Winney
@GrantWinney 因为异常会突然退出该方法。 - James
啊,嗯,这里没有catch块,所以它会抛出异常。我漏了这个。 - Grant Winney

2

R#是正确的,如果您反编译此类(请参见以下代码),则其实现方式为永远不会返回null(它始终返回一个流或抛出异常):

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检查不会改变性能,所以你可以保留它。一般来说,在使用函数返回值之前检查它是否为null并不是一个坏习惯。
  • 就像每个软件一样,R#有时候也会出现bug(例如: 为什么ReSharper认为"thread.Name == null"总是false?),所以不要盲目地遵循它的建议 :)
  • MSDN的示例有时候写得不好,甚至更糟糕,所以不要盲目地复制/粘贴所有他们的示例 :)

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