我希望为函数(或类)编写一个属性,该属性将捕获抛出的任何异常并将其StackTrace
属性设置为string.Empty
。我怎么能这样做?
修改
如果我在普通的C#中无法做到这一点,我怎么能用C#with PostSharp做到这一点?
答案 0 :(得分:3)
[Serializable]
public class MyAspect: OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
throw new MyCustomException(args.Exception);
}
}
public class MyCustomException : Exception
{
public override string StackTrace
{
get
{
//return new StackTrace(10).ToString(); //Skip frames
return string.Empty; //Return empty string
}
}
}
你实际上必须抛出一个新的例外。 @ Ani的例子将简单地重新抛出已经使用相同堆栈跟踪抛出的异常(由于你如何进入方面,它是相同的)。抛出一个新的异常将“改变”堆栈跟踪,但它不会删除它。如果要删除它,则需要抛出自己的类来覆盖堆栈跟踪属性。将旧异常传递给新异常将使旧异常成为内部异常(如果您需要)
您可以使用和不使用PostSharp来完成此操作。 密钥是您的自定义异常类。
给出以下代码
class Program
{
static void Main(string[] args)
{
try
{
Test1();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
}
Console.ReadKey();
}
private static void Test1()
{
try
{
Test2();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
throw e;
}
}
private static void Test2()
{
try
{
Test3();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace + Environment.NewLine);
throw;
}
}
[MyAspect]
private static void Test3()
{
throw new InvalidOperationException();
}
}
[Serializable]
public class MyAspect : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
throw args.Exception;
}
}
输出
在ConsoleApplication5.MyAspect.OnException(MethodExecutionArgs args)在C:\ T est \ Program.cs:第69行at C:\ Test \ Program.cs中的ConsoleApplication5.Program.Test3():第59行 在C:\ Test \ Program.cs中的ConsoleApplication5.Program.Test2():第47行
在ConsoleApplication5.MyAspect.OnException(MethodExecutionArgs args)在C:\ T est \ Program.cs:第69行at C:\ Test \ Program.cs中的ConsoleApplication5.Program.Test3():第59行 在C:\ Test \ Program.cs中的ConsoleApplication5.Program.Test2()中:第52行 在C:\ Test \ Program.cs中的ConsoleApplication5.Program.Test1():第34行
在C:\ Test \ Program.cs:line中的ConsoleApplication5.Program.Test1() 39在ConsoleApplication5.Program.Main(String [] args)中 C:\ Test \ Program.cs:第19行
答案 1 :(得分:3)
异常的原始堆栈跟踪存储在Exception
类的字段中。如果要在不创建自己的异常类型的情况下删除它,可以通过以下反射删除它:
[Serializable]
public sealed class NoStackTraceException : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
RemoveStackTrace(args.Exception);
}
private void RemoveStackTrace(Exception exception)
{
FieldInfo stackTraceField = typeof(Exception).GetField("_stackTrace",
BindingFlags.NonPublic | BindingFlags.Instance);
if (stackTraceField != null)
{
// sets the value of _stackTrace to null
stackTraceField.SetValue(exception, null);
}
}
}
您的异常将不再包含堆栈跟踪。
编辑当然,如果没有PostSharp,您也可以完成同样的事情,只需在catch
区块内完成。