如何告知有返回值的调用方法:ThrowException调用后执行会终止?
问题解决:调用ThrowException后编译器要求返回值的处理
问题根源
你的代码里有两个核心问题导致编译器报错:
- 非UI线程调用
ThrowException时用了BeginInvoke异步执行,当前线程不会立即终止,编译器会认为方法需要继续执行并返回值; - 编译器无法自动推断
ThrowException方法一定会抛出异常,即使UI线程分支是直接throw,仍会要求调用方法返回值。
解决方案
方案1:用[DoesNotReturn]标记方法(推荐C#7.0+)
给ThrowException加上[DoesNotReturn]属性,告诉编译器这个方法永远不会正常返回,同时把BeginInvoke改成Invoke同步执行,确保当前线程会终止:
using System.Diagnostics.CodeAnalysis; internal static class ExceptionHelper { [DoesNotReturn] internal static void ThrowException(Exception e) { var dispatcher = App.Current.Dispatcher; if (dispatcher != null) { if (!dispatcher.CheckAccess()) { // 改用Invoke同步调用,确保当前线程等待UI线程抛出异常后终止 dispatcher.Invoke((ThreadStart)delegate { throw e; }, DispatcherPriority.Normal); } else { throw e; } } // 兜底逻辑:dispatcher为空时直接抛出,保证方法无正常返回 throw e; } }
调用时无需返回值,编译器不再报错:
private SomeEnum DoSomeException() { var e = new NotImplementedException(); ExceptionHelper.ThrowException(e); // 此处不需要return,编译器会识别方法已终止 }
方案2:泛型返回方法(兼容低版本C#)
如果项目用的是C#7.0以下版本,可以封装泛型方法,返回一个永远不会被执行到的默认值,满足编译器要求:
internal static class ExceptionHelper { internal static T ThrowException<T>(Exception e) { var dispatcher = App.Current.Dispatcher; if (dispatcher != null) { if (!dispatcher.CheckAccess()) { dispatcher.Invoke(() => throw e, DispatcherPriority.Normal); } else { throw e; } } throw e; // 仅为满足编译器语法要求,永远不会执行到 return default(T); } }
调用时直接返回该方法的结果:
private SomeEnum DoSomeException() { var e = new NotImplementedException(); return ExceptionHelper.ThrowException<SomeEnum>(e); }
重要提醒
- 绝对不能用
BeginInvoke:异步调用会让当前线程继续执行,不仅编译器报错,还会导致方法后续逻辑(如果有)意外执行,彻底违背“抛出异常即终止”的初衷; [DoesNotReturn]需要引用System.Diagnostics.CodeAnalysis命名空间,若项目版本过低,需在项目文件中设置<LangVersion>7.0</LangVersion>或更高版本。
内容的提问来源于stack exchange,提问作者T. Hench
相关产品推荐
相关产品推荐

