我尝试设置一个异常逻辑,系统的一部分可以回退到意外的行为。
应该继承一个新类,该类继承Exception
对象并使用新的“exit”扩展功能,该“exit”包含对用户的错误信号和日志记录例程。
我可能需要更好地理解throw
的用法,但我可以通过这样做来使其相当透明:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}
我想你可以看到我在这里要做的事情。
当应用程序无法提供请求时,我尝试抛出。 throw用于通过异常执行执行(为调用者生成足够的错误代码)。此示例是“我知道你给了我9但这里只允许1-8”的类型错误,“errorCode进一步发送到UnexpectedQueryException(...)
。
不幸的是,应用程序将throw作为未处理并关闭我的线程,并且应用程序在重新启动之前将无法运行。除了这种情况,我还会使用这个抛出语句。
在我看来,这是非常有效的。
这里有什么最佳做法?
我希望异常处理能够在不同场景(如上所述)上“回退”,因此我总是有一种简单的方法将错误传达给用户(这意味着我可以发送有关异常位置的非常准确的信息) )。
此外,我当然希望应用程序继续工作。
来自异常逻辑的部分代码,
public class UnexpectedQueryException: CommunicationException
{
public UnexpectedQueryException(SomeObject object, ErrorCode errorCode) : base("UnexpectedQueryException", object, errorCode)
{
.........
}
}
反过来,它继承了基本的Exception对象,
public class CommunicationException : Exception
{
..some fields..
public CommunicationException(string Message, SomeObject object, ErrorCode errorcode)
{
.....
}
public CommunicationException() : base("CommunicationException")
{ }
}
答案 0 :(得分:6)
如果你在代码中抛出一个异常,你需要抓住它并用它做某事 - 如果你没有,你有不处理它。< / p>
如果你扔在catch
区块内,同样适用。你抛出了一个异常,它将继续传播直到找到合适的catch块。如果不存在,则表示未处理。
您需要构建更高级别的(UI)代码,以便捕获正确类型的异常并将您想要的信息传达给用户:
try
{
// code that can throw
}
catch(VerySpecificException ex)
{
// communicate to user details about VerySpecificException.
// possibly log.
// Do not re-throw or throw a new excpetion as it is now handled.
}
catch(AnotherSpecificException ex)
{
// communicate to user details about AnotherSpecificException.
}
catch(LessSpecificException ex)
{
// communicate to user details about LessSpecificException.
}
catch(EveLessSpecificException ex)
{
// communicate to user details about EvenLessSpecificException.
}
答案 1 :(得分:3)
您需要了解如何以及何时捕获异常。
在(工作线程)线程中抛出异常的令人讨厌的事情是任何顶级异常处理程序(例如program.cs中的try / catch)都不会捕获并记录线程中抛出的异常。因此,您应该始终在线程输入方法中使用常规try / catch,至少如果您不希望应用程序死亡。
一个非常简单的规则是,您应该只捕获可以处理的异常,以便从方法中提供预期结果。在入口点防止应用程序死亡(但有时最好让应用程序死掉)。
为了更好地理解异常,您可能需要阅读我关于例外的博客文章:http://blog.gauffin.org/tag/exceptions/
答案 2 :(得分:1)
throw
不会处理错误但会引发错误。如果没有throw
,则无法处理错误。
通过捕获它来处理异常。您需要在代码中的某个位置调用try - catch
块GetVersion
(或代码中的某个位置调用调用GetVersion
的代码等)。如果您未在调用层次结构中捕获UnexpectedQueryException
,则表示未处理,您的应用程序将停止。
调用GetVersion
不同时间(不处理异常)的示例。
List<SomeObject> GetAllVersions(byte[] bytes)
{
var result = new List<SomeObject>();
foreach (byte b in bytes)
{
result.Add(GetVersion(b));
}
return result;
}
现在由来处理来处理异常。您可以在循环中执行此操作,以便获得包含所有成功检索的对象的结果:
foreach (byte b in bytes)
{
try
{
result.Add(GetVersion(b));
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
}
}
或者您可以在应用程序的其他级别处理异常,例如:将对GetAllVersions
的调用包装成try-catch
块:
List<SomeObject> = null;
try
{
versionList = GetAllVersions(bytes)
// do something with versionList
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
// Note that versionList will be null in error case
}
这是例外的主要优点。它们在整个调用堆栈中传播。因此,您不需要在错误之后的代码行中处理它,而是在您认为合适的应用程序中的某处。
答案 3 :(得分:-3)
不幸的是,应用程序将throw视为未处理并关闭 我的线程和应用程序在重启之前不会运行。除此之外 我也会在catch语句中使用此方法。
您提供的代码会始终引发异常,因为您尝试将 byte 类型的值类型转换为 SomeObj 类型的引用类型:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}