gpt4 book ai didi

c# - 关于通用 try catch 的建议

转载 作者:太空狗 更新时间:2023-10-29 22:08:20 25 4
gpt4 key购买 nike

这不是什么大问题,而是更多的反馈和想法。我一直在考虑实现已经通过我们内部团队彻底测试的方法。我想编写一个通用的异常捕获方法和报告服务。

我意识到这不像“try-catch” block 那么简单,但允许使用统一的方法来捕获异常。理想情况下,我想执行一个方法,提供失败回调并记录调用方法的所有参数。

通用尝试执行。

public class ExceptionHelper
{
public static T TryExecute<T, TArgs>(Func<TArgs, T> Method, Func<TArgs, T> FailureCallBack, TArgs Args)
{
try
{
return Method(Args);
}
catch (Exception ex)
{
StackTrace stackTrace = new StackTrace();
string method = "Unknown Method";
if (stackTrace != null && stackTrace.FrameCount > 0)
{
var methodInfo = stackTrace.GetFrame(1).GetMethod();
if (methodInfo != null)
method = string.Join(".", methodInfo.ReflectedType.Namespace, methodInfo.ReflectedType.Name, methodInfo.Name);
}
List<string> aStr = new List<string>();
foreach (var prop in typeof(TArgs).GetProperties().Where(x => x.CanRead && x.CanWrite))
{
object propVal = null;
try
{
propVal = prop.GetValue(Args, null);
}
catch
{
propVal = string.Empty;
}
aStr.Add(string.Format("{0}:{1}", prop.Name, propVal.ToString()));
}
string failureString = string.Format("The method '{0}' failed. {1}", method, string.Join(", ", aStr));
//TODO: Log To Internal error system
try
{
return FailureCallBack(Args);
}
catch
{
return default(T);
}
}
}
}

我所知道的缺点。

  • 使用反射的性能损失
  • MethodBase (methodInfo) 可能无法通过优化获得
  • 围绕错误处理程序的 try-catch。基本上我可以使用 TryExecute 包装器来围绕错误回调进行 try-catch,但这可能会导致堆栈溢出情况。

这是一个示例实现

var model = new { ModelA = "A", ModelB = "B" };
return ExceptionHelper.TryExecute((Model) =>
{
throw new Exception("Testing exception handler");
},
(Model) =>
{
return false;
},
model);

感谢想法和评论。

最佳答案

很多代码要放入catch,包括另外两个 try/捕捉 block 。如果你问我,这似乎有点矫枉过正,有很大的风险,进一步的异常可能会掩盖实际的异常,并且错误信息将会丢失。

此外,为什么返回默认值(T)?返回默认值或空值作为问题的指示通常是非常草率的。如果没有别的,它需要相同的条件来包裹对方法的每次调用以检查返回并响应......现在已经在其他地方出现的一些错误。

老实说,这个用法示例看起来也很困惑。看起来您最终会用错误捕获代码掩盖实际的业务逻辑。整个代码库看起来就像一系列错误陷阱,实际的业务逻辑隐藏在其中的某个地方。这将有值(value)的焦点从应用程序的实际意图上移开,并将一些背景基础设施重要性(日志记录)放在最前面。

简化。

如果方法中发生异常,您通常有两个明智的选择:

  1. 捕获(有意义地处理)方法中的异常。
  2. 让异常在堆栈中冒泡,以便在其他地方捕获。

绝对没有异常逃脱了它发生的方法的范围。事实上,异常正是为了做到这一点而设计的,并带有关于发生了什么和在哪里发生的有用堆栈信息。 (而且,如果您向异常添加有意义的运行时上下文,它还可以携带有关原因的信息。)

事实上,编译器甚至巧妙地暗示了这一点。以这两种方式为例:

public int Sum(int first, int second)
{
// TODO: Implement this method
}

public int Product(int first, int second)
{
throw new NotImplementedException();
}

这些方法中的一个会编译,其中一个不会。编译器错误将声明并非所有代码路径都返回前一个方法的值。但为什么不是后者呢?因为抛出异常是一种完全可以接受的方法退出策略。这就是方法如何放弃它正在做的事情(一个它应该尝试做的事情,什么都不做),让调用代码处理这个问题。 p>

代码的阅读方式应清楚地表达所建模的业务概念。错误处理是一个重要的基础设施概念,但它只是……基础设施。代码实际上应该尖叫正在建模的业务概念,清晰简洁。基础设施问题不应妨碍这一点。

关于c# - 关于通用 try catch 的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12255270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com