仕事で .Net Framework 4.0 を触る機会があり、その時に例外の HResult によって処理を切り替える必要があったがアクセスができなかったので理由を調べた。
忘備録として記録をしておく。
Exception の HResult のアクセス修飾子
Exception の HResult プロパティは .Net Framework のバージョンによってアクセス修飾子が異なる。
.Net Framework 4.5 より前では以下のようにな定義になっている。
namespace System
{
public class Exception : ISerializable, _Exception
{
// 略
protected int HResult { get; set; }
// 略
}
}
そのため HResult には直接アクセスすることができない。
.Net Framework 4.5 以降では以下のような定義に変更されている。
namespace System
{
public class Exception : ISerializable, _Exception
{
// 略
public int HResult { get; protected set; }
// 略
}
}
setter のみ protected になっているため例外のエラーコードに HResult プロパティから直接アクセスが可能になった。
.Net Framework 4.5 より前のバージョンでライブラリ等を作るときの HResult へのアクセス方法
HResult にアクセスする場合は次のようにリフレクションを使用する。
try
{
// 例外発生
}
catch(Exception ex)
{
var propertyInfo = ex.GetType()
.GetProperty("HResult",
System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.GetProperty
| System.Reflection.BindingFlags.NonPublic
// この Project のターゲットが .Net Framework 4.5 より前であっても
// .Net Framework 4.5 以上のアセンブリが参照される可能性があるので Public を指定しておく
| System.Reflection.BindingFlags.Public
);
var hResult = (int)propertyInfo.GetValue(ex,null);
}
ただし、もしライブラリとして作成をする場合は .Net Framework 4.5 以上のプロジェクトから呼ばれる可能性もあるのでコメントのように System.Reflection.BindingFlags.Public
を指定する。
サンプルコードをここに上げておく。