MSDNを読みましたが、この概念を理解できませんでした。
私が間違っている場合は修正してください、
現在の例外とともに、innerexceptionが使用されます。
内部例外が最初に発生し、次に現在の例外が発生し(例外がある場合)、それがInnerException
がnull
に対してチェックされる理由です。内部例外を保持するには、それをパラメーターとして渡す必要があります。
これでいいの?
以下のコードを見ることができます。
最初のステップでは、「abc」を整数に解析します。 FormatExceptionが発生します。
Catchブロックで、テキストファイルを開いて例外メッセージを記録しようとしています。しかし、このファイルは存在しませんでした。 FileNotFoundExceptionが発生します。
2番目の例外が発生した原因を知りたいので、2番目の例外のコンストラクターに最初の例外(またはFormatException)を追加します。
現在、最初の例外は2番目の例外のInnerExceptionです。
Catchブロックでは、InnerExceptionのプロパティにアクセスして、最初の例外が何であるかを知ることができます。
便利ですか?
using System;
using System.IO;
public class Program
{
public static void Main( )
{
try
{
try
{
var num = int.Parse("abc");
}
catch ( Exception inner )
{
try
{
var openLog = File.Open("DoesNotExist", FileMode.Open);
}
catch
{
throw new FileNotFoundException("OutterException", inner);
}
}
}
catch ( Exception e)
{
string inMes, outMes;
if (e.InnerException != null)
inMes = e.InnerException.Message;
outMes = e.Message;
}
}
}
内部例外は、現在の例外を引き起こした例外です。
コードがキャッチした例外とは異なる例外を表示したいが、元のコンテキストを破棄したくない場合に使用します。
前に述べたように、新しい例外に以前の例外に関する情報を持たせるには、コンストラクターパラメーターとして新しい例外に渡します。
通常、null内部例外は、現在の例外が例外状況の根本原因であることを意味します。
例外オブジェクトは、catch
ブロックに到達するまで読み取り専用です。コードは例外を処理するために何もできない場合がありますが、新しい例外を作成し、最初にスローされた例外をラップすることで情報を追加できますその中。これにより、情報を追加できますが、元の例外からすべての情報をフィールドごとにコピーする必要はありません(スローされる例外のタイプがわからない場合は不可能な場合もあります)。
これは、例外を処理するすべてのビットを使用する私のプロジェクトからのわずかに変更されたスニペットです。
private void SomeFunction(string username, string password)
{
try
{
try
{
_someObject.DoSpecialPrivilegedFunction(username, password);
}
catch (UnauthorizedAccessException ex)
{
throw new UserUnauthorizedException(username, "DoSpecialPrivilegedFunction", ex);
}
catch (IOException ex)
{
throw new UserModuleActionException("A network IO error happend.", username, "DoSpecialPrivilegedFunction", ex);
}
//Other modules
}
catch (Exception ex)
{
//If it is one of our custom expections, just re-throw the exception.
if (ex is UserActionException)
throw;
else
throw new UserActionException("A unknown error due to a user action happened.", username, ex);
}
}
//elsewhere
[Serializable]
public class UserUnauthorizedException : UserModuleActionException
{
private const string DefaultMessage = "The user attempted to use a non authorized module";
public UserUnauthorizedException()
: base(DefaultMessage)
{
}
public UserUnauthorizedException(string message)
: base(message)
{
}
public UserUnauthorizedException(string message, Exception innerException)
: base(message, innerException)
{
}
public UserUnauthorizedException(string username, string module, Exception innerException = null) : base(DefaultMessage, username, module, innerException)
{
}
protected UserUnauthorizedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
[Serializable]
public class UserModuleActionException : UserActionException
{
private readonly string _module;
public UserModuleActionException()
{
}
public UserModuleActionException(string message) : base(message)
{
}
public UserModuleActionException(string message, Exception innerException) : base(message, innerException)
{
}
public UserModuleActionException(string message, string username, string module, Exception innerException = null)
: base(message, username, innerException)
{
_module = module;
}
protected UserModuleActionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public virtual string Module
{
get { return _module; }
}
public override string Message
{
get
{
string s = base.Message;
if (!String.IsNullOrEmpty(_module))
{
return s + Environment.NewLine + String.Format("Module: {0}", _module);
}
return base.Message;
}
}
}
[Serializable]
public class UserActionException : Exception
{
private readonly string _username;
public UserActionException()
{
}
public UserActionException(string message)
: base(message)
{
}
public UserActionException(string message, Exception innerException)
: base(message, innerException)
{
}
public UserActionException(string message, string username, Exception innerException = null)
: base(message, innerException)
{
_username = username;
}
protected UserActionException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public override string Message
{
get
{
string s = base.Message;
if (!String.IsNullOrEmpty(_username))
{
return s + Environment.NewLine + String.Format("Username: {0}", _username);
}
return base.Message;
}
}
public virtual string Username
{
get { return _username; }
}
}