我可以重载 throw 关键字吗?
Can I overload the throw keyword?
我想重载 throw 关键字以捕获从 Exception 继承的 class 并让它在实际抛出之前执行一些日志记录和其他操作。这可能吗?还是我必须使用常规函数?
我试过:
public class cSilException : Exception
{
private string m_strMsg;
public override void throw(cSilException ex)
{
}
...
...
}
您要做的是向您的异常添加一个构造函数,并在该构造函数中执行您需要执行的任何操作。
public class cSilException : Exception
{
//constructor
public cSilException()
{
// do stuff here
}
}
你的"overloading the throw keyword"概念很,呃,怎么说呢,迷幻。
当然,正如许多人指出的那样,如果您打算做日志记录之类的事情,最好避免这样做。 Alois Kraus 发布了另一个答案并提出了很好的建议。
您不能重载 throw
它是语言的组成部分(不是 class 的成员)
如果你想处理一个特定的异常,你应该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
。
查找 Exception
class 的方法和成员。您可以像这样为 cSilException
定义构造函数
public cSilException(string message)
{
Message = message;
}
比 catch (cSilException ex)
做 Console.WriteLine(ex.Message);
我不建议在异常的构造函数中记录任何内容,因为它违反了单一责任原则并且被认为是糟糕的设计。此外,创建异常的事实并不一定意味着它已被抛出,此外,可以捕获并重新抛出异常 - 这些事情可能会导致不正确的日志消息。
相反,您可以使用应用程序范围的异常处理程序,它将根据您预定义的策略处理异常。例如,您可以查看 Enterprise Library Exception Handling Block and specifically this section.
注册事件 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);
}
这将导致:
Got invalid cast: System.InvalidCastException:
The object of the type
"System.Int32"
cannot be converted to "System.String". at
ThrowTest.Program.DoOneLevelBelow()
in
d:\Media\Blog\ThrowTest\Program.cs:line 31.
请注意,由于您在堆栈展开之前收到异常,因此您只会看到它确实发生的方法,而不是调用方法,因为堆栈尚未展开。
如果你想要完整的调用堆栈,你可以使用 Environment.StackTrace
来获取所有堆栈帧。
我想重载 throw 关键字以捕获从 Exception 继承的 class 并让它在实际抛出之前执行一些日志记录和其他操作。这可能吗?还是我必须使用常规函数?
我试过:
public class cSilException : Exception
{
private string m_strMsg;
public override void throw(cSilException ex)
{
}
...
...
}
您要做的是向您的异常添加一个构造函数,并在该构造函数中执行您需要执行的任何操作。
public class cSilException : Exception
{
//constructor
public cSilException()
{
// do stuff here
}
}
你的"overloading the throw keyword"概念很,呃,怎么说呢,迷幻。
当然,正如许多人指出的那样,如果您打算做日志记录之类的事情,最好避免这样做。 Alois Kraus 发布了另一个答案并提出了很好的建议。
您不能重载 throw
它是语言的组成部分(不是 class 的成员)
如果你想处理一个特定的异常,你应该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
。
查找 Exception
class 的方法和成员。您可以像这样为 cSilException
定义构造函数
public cSilException(string message)
{
Message = message;
}
比 catch (cSilException ex)
做 Console.WriteLine(ex.Message);
我不建议在异常的构造函数中记录任何内容,因为它违反了单一责任原则并且被认为是糟糕的设计。此外,创建异常的事实并不一定意味着它已被抛出,此外,可以捕获并重新抛出异常 - 这些事情可能会导致不正确的日志消息。
相反,您可以使用应用程序范围的异常处理程序,它将根据您预定义的策略处理异常。例如,您可以查看 Enterprise Library Exception Handling Block and specifically this section.
注册事件 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);
}
这将导致:
Got invalid cast:
System.InvalidCastException:
The object of the type"System.Int32"
cannot be converted to "System.String". atThrowTest.Program.DoOneLevelBelow()
in d:\Media\Blog\ThrowTest\Program.cs:line 31.
请注意,由于您在堆栈展开之前收到异常,因此您只会看到它确实发生的方法,而不是调用方法,因为堆栈尚未展开。
如果你想要完整的调用堆栈,你可以使用 Environment.StackTrace
来获取所有堆栈帧。