2015-04-02 4 views
1

Я пытаюсь написать хорошо документированный код, который также будет легко отлаживать, если обрабатывается какое-то исключение. Поэтому мои методы вызывают исключения, и они собраны в журнале, который я могу просматривать. Однако при создании нового исключения писать сообщения сложнее. Я хотел бы написать простую утилиту, которая будет собирать:Исключения из C#

  • имя текущего класса
  • имя текущего метода
  • параметры метода

это может быть достигнуто в некоторых Простой способ? Кроме того, есть ли лучший способ сделать такие журналы исключений? Возможно, эта проблема решается по-другому, поэтому, пожалуйста, поделитесь своим опытом со мной :)

+5

Ну, есть StackTrace, уже включенный в исключение, что в значительной степени таково. –

+0

В этом формате ваш вопрос слишком широк. Также лучше хранить/записывать трассировку стека на исключение. Вы можете посмотреть в Интернете, как взять трассировку стека. – mybirthname

+0

@ Pierre-Luc Pineault Замечательно! Я не знал, что он существует. Спасибо. Если вы напишете это как ответ, я дам вам чек. –

ответ

1

Исключение уже содержит эту информацию в ее StackTrace.

Чтобы получить доступ к нему, просто использовать общественный поглотитель:

catch(Exception ex) 
{ 
    string trace = ex.StackTrace; 
} 

Если вы хотите зарегистрировать ее, большинство лесозаготовителей имеют перегрузку, которая принимает исключение. Трассировка сообщения и стека будет регистрироваться.

Например, с log4net, вы можете использовать метод void Error(object message, Exception t);:

catch(Exception ex) 
{ 
    logger.Error("More details", ex); 
} 
1

привет, чтобы получить имя метода с подписями исправление

 //get the stack trace 
     StackTrace stackTrace = new StackTrace(); 
     //the count may vary 
     MethodBase CallingMethod = stackTrace.GetFrame(2).GetMethod(); 

     //Method called by      
     string _signatures = MethodInfoExtensions.GetSignature((MethodInfo)CallingMethod)); 

и класс

public static class MethodInfoExtensions 
{ 
    /// <summary> 
    /// Return the method signature as a string. 
    /// </summary> 
    /// <param name="method">The Method</param> 
    /// <param name="callable">Return as an callable string(public void a(string b) would return a(b))</param> 
    /// <returns>Method signature</returns> 
    public static string GetSignature(this MethodInfo method, bool callable = false) 
    { 
     var firstParam = true; 
     var sigBuilder = new StringBuilder(); 
     if (callable == false) 
     { 
      if (method.IsPublic) 
       sigBuilder.Append("public "); 
      else if (method.IsPrivate) 
       sigBuilder.Append("private "); 
      else if (method.IsAssembly) 
       sigBuilder.Append("internal "); 
      if (method.IsFamily) 
       sigBuilder.Append("protected "); 
      if (method.IsStatic) 
       sigBuilder.Append("static "); 
      sigBuilder.Append(TypeName(method.ReturnType)); 
      sigBuilder.Append(' '); 
     } 
     sigBuilder.Append(method.Name); 

     // Add method generics 
     if (method.IsGenericMethod) 
     { 
      sigBuilder.Append("<"); 
      foreach (var g in method.GetGenericArguments()) 
      { 
       if (firstParam) 
        firstParam = false; 
       else 
        sigBuilder.Append(", "); 
       sigBuilder.Append(TypeName(g)); 
      } 
      sigBuilder.Append(">"); 
     } 
     sigBuilder.Append("("); 
     firstParam = true; 
     var secondParam = false; 
     foreach (var param in method.GetParameters()) 
     { 
      if (firstParam) 
      { 
       firstParam = false; 
       if (method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false)) 
       { 
        if (callable) 
        { 
         secondParam = true; 
         continue; 
        } 
        sigBuilder.Append("this "); 
       } 
      } 
      else if (secondParam == true) 
       secondParam = false; 
      else 
       sigBuilder.Append(", "); 
      if (param.ParameterType.IsByRef) 
       sigBuilder.Append("ref "); 
      else if (param.IsOut) 
       sigBuilder.Append("out "); 
      if (!callable) 
      { 
       sigBuilder.Append(TypeName(param.ParameterType)); 
       sigBuilder.Append(' '); 
      } 
      sigBuilder.Append(param.Name); 
     } 
     sigBuilder.Append(")"); 
     return sigBuilder.ToString(); 
    } 

    /// <summary> 
    /// Get full type name with full namespace names 
    /// </summary> 
    /// <param name="type">Type. May be generic or nullable</param> 
    /// <returns>Full type name, fully qualified namespaces</returns> 
    public static string TypeName(Type type) 
    { 
     var nullableType = Nullable.GetUnderlyingType(type); 
     if (nullableType != null) 
      return nullableType.Name + "?"; 

     if (!type.IsGenericType) 
      switch (type.Name) 
      { 
       case "String": return "string"; 
       case "Int32": return "int"; 
       case "Decimal": return "decimal"; 
       case "Object": return "object"; 
       case "Void": return "void"; 
       default: 
        { 
         return string.IsNullOrWhiteSpace(type.FullName) ? type.Name : type.FullName; 
        } 
      } 

     var sb = new StringBuilder(type.Name.Substring(0, 
     type.Name.IndexOf('`')) 
     ); 
     sb.Append('<'); 
     var first = true; 
     foreach (var t in type.GetGenericArguments()) 
     { 
      if (!first) 
       sb.Append(','); 
      sb.Append(TypeName(t)); 
      first = false; 
     } 
     sb.Append('>'); 
     return sb.ToString(); 
    } 

} 
Смежные вопросы