C# 中的异常

Exceptions in C#

我正在尝试编写文档完善的代码,如果处理了某些异常,该代码也将易于调试。因此,我的方法会抛出异常,它们会收集在我可以浏览的日志中。但是,在抛出新的异常时,写复杂的消息确实不太合适。我想编写一个简单的实用程序来收集:

这可以通过一些简单的方法实现吗?另外,是否有更好的方法来制作此类异常日志?也许这个问题正在以不同的方式解决,所以请与我分享您的经验:)

异常已在其 StackTrace 中包含此信息。

要访问它,只需使用 public getter:

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

如果你想记录它,大多数记录器都有一个重载,它需要一个异常。将记录消息和堆栈跟踪。

例如,对于log4net,你可以使用方法void Error(object message, Exception t);:

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

您好获取带有签名的方法的名称修复是

        //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));

和 class

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();
    }

}