【问题标题】:Compiler Error With "DoesNotReturn" Attribute带有“DoesNotReturn”属性的编译器错误
【发布时间】:2021-06-18 10:56:00
【问题描述】:

我在 net-standard 2.1 (C# 8.0) 项目中实现了一些静态 throw 辅助方法。

[DoesNotReturn]
public static void InvalidOperation(String message, String caller, String path, Int32 line)
{
  throw new InvalidOperationException($"{message}\n{caller}|{path}|{line}");
}

我想在 NET 5.0 项目中使用它们,例如:

public static BitmapSource GetBitmapSource(String uri)
{
    if (Uri.TryCreate(uri, UriKind.RelativeOrAbsolute, out Uri? _uri))
    {
        return new BitmapImage(_uri);
    }

    Throw.InvalidOperation( $"Invalid uri {uri}.");
}

但是编译器还是返回错误CS0161:“Not all code paths return a value”

【问题讨论】:

  • puplic?好的,您不应该使用 Throw.InvalidOperation( $"Invalid uri {uri}."); 之类的方法抛出异常您可以执行异常 fablic 并使用类似:throw MyExceptionGenerator.InvalidOperation($"Invalid uri {uri}.");,但最佳做法是通过 new 运算符生成异常 - 您应该生成新的异常类并使用如下: throw new MyInvalidOperaionException($"Invalid uri {uri}.")
  • 我喜欢使用 CallerMemberName、CallerFilePath 和 CallerLineAttributes 来定位引发异常的位置。这就是我使用这些辅助方法的原因。我已经多次看过这些辅助方法。喜欢这里:endjin.com/blog/2020/08/…
  • 属性可以帮助编译器进行额外的分析,但据我所知,它们仍然不允许你违反可达性的语言规则......你的方法结束就编译器而言仍然可以访问。
  • 这不是我想听到的,斯基特先生。 :-( 不过,感谢您的澄清。
  • 类似于 ExceptionDispatchInfo.Throw。我们知道它后面的行无法访问,但语言需要返回。您可以输入一个虚拟返回或抛出 null,但这不是最好的事情......或者只是切换到上面评论中的建议,throw ThrowHelper.Whatever() 或切换您执行检查的顺序

标签: c# code-analysis c#-8.0


【解决方案1】:

先写异常路径:

public static BitmapSource GetBitmapSource(String uri)
{
    if (!Uri.TryCreate(uri, UriKind.RelativeOrAbsolute, out Uri? _uri))
    {
        Throw.InvalidOperation( $"Invalid uri {uri}.");
    }

    return new BitmapImage(_uri);
}

现在,就编译器而言,方法返回。


要考虑的另一件事是让辅助方法返回异常,而不是抛出异常。调用它的方法可以抛出它。这样编译器就会知道它抛出了。这也意味着您不会在异常的堆栈跟踪中获得辅助方法。


顺便说一句,作为发现这个问题的人的参考,我相信问题中的辅助方法旨在使用这些:Reserved attributes: Determine caller information

【讨论】:

  • 谢谢。在大多数情况下,返回异常而不是抛出似乎是最好的解决方案。我只是期望编译器会从属性中推断出可达性。是的,我的意思是链接的调用者属性。感谢您的澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
相关资源
最近更新 更多