I seguenti esempi di codice forniscono un contesto alla mia domanda.
La classe Room è inizializzata con un delegato. Nella prima implementazione della classe Room, non ci sono guardie contro i delegati che lanciano eccezioni. Tali eccezioni diventeranno la proprietà North, dove viene valutato il delegato (nota: il metodo Main () dimostra come viene utilizzata un'istanza Room nel codice client):
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
}
}
Essendo che preferirei fallire nella creazione di un oggetto piuttosto che durante la lettura della proprietà North, cambio il costruttore in privato e introduco un metodo factory statico chiamato Create (). Questo metodo intercetta l'eccezione generata dal delegato e genera un'eccezione wrapper con un messaggio di eccezione significativo:
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;
}
}
Il blocco try-catch rende il metodo Create () impuro?