次のコード例は、私の質問の背景を示しています。
Roomクラスはデリゲートで初期化されます。Roomクラスの最初の実装では、例外をスローするデリゲートに対するガードはありません。このような例外は、デリゲートが評価されるNorthプロパティにバブルアップします(注:Main()メソッドは、クライアントコードでRoomインスタンスがどのように使用されるかを示します)。
public sealed class Room
{
private readonly Func<Room> north;
public Room(Func<Room> north)
{
this.north = north;
}
public Room North
{
get
{
return this.north();
}
}
public static void Main(string[] args)
{
Func<Room> evilDelegate = () => { throw new Exception(); };
var kitchen = new Room(north: evilDelegate);
var room = kitchen.North; //<----this will throw
}
}
Northプロパティを読み取るときではなく、オブジェクトの作成時に失敗するので、コンストラクターをprivateに変更し、Create()という名前の静的ファクトリーメソッドを導入します。このメソッドは、デリゲートによってスローされた例外をキャッチし、意味のある例外メッセージを持つラッパー例外をスローします。
public sealed class Room
{
private readonly Func<Room> north;
private Room(Func<Room> north)
{
this.north = north;
}
public Room North
{
get
{
return this.north();
}
}
public static Room Create(Func<Room> north)
{
try
{
north?.Invoke();
}
catch (Exception e)
{
throw new Exception(
message: "Initialized with an evil delegate!", innerException: e);
}
return new Room(north);
}
public static void Main(string[] args)
{
Func<Room> evilDelegate = () => { throw new Exception(); };
var kitchen = Room.Create(north: evilDelegate); //<----this will throw
var room = kitchen.North;
}
}
try-catchブロックはCreate()メソッドを不純にしますか?
Create
それを呼び出すため、不純な関数でもあります。
Create
関数は、プロパティを取得するときに例外を得ることからあなたを保護することはできません。デリゲートがスローされる場合、実際には、特定の条件下でのみスローされる可能性が非常に高くなります。建設中に投げるための条件が存在しない可能性がありますが、プロパティを取得するときに存在します。