我想重载 throw 关键字以捕获一个继承自Exception的类,并让它在实际抛出之前执行一些日志记录和其他操作。这可能吗?或者我必须使用常规功能吗?
我试过了:
public class cSilException : Exception
{
private string m_strMsg;
public override void throw(cSilException ex)
{
}
...
...
}
答案 0 :(得分:24)
注册事件AppDomain.FirstChanceException.
在实际抛出之前,您将获得所有异常。在事件处理程序中,您可以检查exception
并执行所需的日志记录。
没有魔力,没有糟糕的设计。
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
DoBadThings();
}
private static void DoBadThings()
{
DoOneLevelBelow();
}
private static void DoOneLevelBelow()
{
for(int i=0;i<10;i++)
{
try
{
if (i == 5)
{
var invalidCast = (string)((object)i);
}
else
{
throw new InvalidTimeZoneException();
}
}
catch
{
}
}
}
static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
if( e.Exception is InvalidCastException)
{
LogInvalidCast((InvalidCastException)e.Exception);
}
}
private static void LogInvalidCast(InvalidCastException invalidCastException)
{
Console.WriteLine("Got Invalid cast: {0}", invalidCastException);
}
这将导致:
获得无效演员:
System.InvalidCastException:
该类型的对象"System.Int32"
无法转换为“System.String”。在ThrowTest.Program.DoOneLevelBelow()
in d:\ Media \ Blog \ ThrowTest \ Program.cs:第31行。
请注意,因为你在解开堆栈之前得到异常,你将只看到它发生的方法,但不会看到调用方法,因为堆栈还没有解开。
如果需要完整的调用堆栈,可以使用Environment.StackTrace
来获取所有堆栈帧。
答案 1 :(得分:21)
您要做的是在您的异常中添加一个构造函数,并在该构造函数中执行您需要执行的任何操作。
public class cSilException : Exception
{
//constructor
public cSilException()
{
// do stuff here
}
}
你的概念&#34;重载了throw关键字&#34;非常,呃,怎么说,迷幻。
当然,正如许多人所指出的那样,如果你打算做日志记录等事情,最好避免这样做。 Alois Kraus发布了另一个非常好的建议。
答案 2 :(得分:8)
我不建议在异常的构造函数中记录任何内容,因为它违反了单一责任原则并被认为是一个糟糕的设计。此外,创建异常的事实并不一定意味着它已被抛出,此外,异常可以被捕获和重新抛出 - 这些可能会导致错误的日志记录消息。
相反,您可以使用应用程序范围的异常处理程序,该处理程序将根据您的预定义策略处理异常。例如,您可以查看Enterprise Library Exception Handling Block,特别是this section。
答案 3 :(得分:2)
你不能重载throw
它是语言的一个组成部分(不是一个类的成员)
如果您想处理特定的异常,您应该catch
该异常:
try
{
// your code, which throws some exceptions
}
catch(cSilException csEx)
{
// handle csEx
throw; // rethrow this exception
}
catch(Exception ex)
{
// handle all other exceptions
}
此代码捕获与其他所有异常不同的代码块中的特殊异常cSilException
。
答案 4 :(得分:2)
查找Exception
类的方法和成员。您可以像{/ p>这样定义cSilException
的构造函数
public cSilException(string message)
{
Message = message;
}
而不是catch (cSilException ex)
做Console.WriteLine(ex.Message);