我的很多C#代码遵循这种模式:
void foo(string param1, string param2, string param3) { try { // do something... } catch(Exception ex) { LogError(String.Format("Error in foo(param1={0}, param2={1}, param3={2}), exception={3}", param1, param2, param3, ex.Message)); } }
有没有办法在.NET中获取函数的键/值列表,以便我可以调用另一个函数来构造我的错误记录字符串?或者你有更通用/更好的方法吗?
您可以使用Reflection和必须以正确的顺序将参数传递给LogError的约定:
private static void MyMethod(string s, int x, int y) { try { throw new NotImplementedException(); } catch (Exception ex) { LogError(MethodBase.GetCurrentMethod(), ex, s, x, y); } } private static void LogError(MethodBase method, Exception ex, params object[] values) { ParameterInfo[] parms = method.GetParameters(); object[] namevalues = new object[2 * parms.Length]; string msg = "Error in " + method.Name + "("; for (int i = 0, j = 0; i < parms.Length; i++, j += 2) { msg += "{" + j + "}={" + (j + 1) + "}, "; namevalues[j] = parms[i].Name; if (i < values.Length) namevalues[j + 1] = values[i]; } msg += "exception=" + ex.Message + ")"; Console.WriteLine(string.Format(msg, namevalues)); }
您可以在PostSharp中使用面向方面的编程(请参阅http://www.postsharp.org,以及http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx上的教程)).基本上你可以这样做:
public class LogExceptionAttribute : OnExceptionAspect { public override void OnException(MethodExecutionEventArgs eventArgs) { log.error("Exception occurred in method {0}", eventArgs); } } [LoggingOnExceptionAspect] public foo(int number, string word, Person customer) { // ... something here throws an exception }
也许不是你想要的,但我相信它可以根据你的需要进行调整.
没有办法做到这一点.
通常的做法是不捕获异常,除非你能处理它们.
也就是说,您通常只会捕获异常并将它们记录在顶级异常处理程序中.然后,您将获得堆栈跟踪,但当然不会获得堆栈中所有方法调用的所有参数的详细信息.
显然,在调试时,您需要尽可能多的细节.其他实现方法是:
使用Debug.Assert语句来测试您正在进行的假设.
使用可以选择性激活的日志记录来检测应用程序.我使用Log4Net,但也有其他选择,包括使用System.Diagnostics.Trace类.
在任何情况下,如果您只捕获异常以记录它们(我在n层应用程序的层边界执行此操作,以便在服务器上记录异常),那么您应该始终重新抛出它们:
try { ... } catch(Exception ex) { log(ex); throw; }