I seguenti esempi di codice forniscono un contesto alla mia domanda.
La classe Room viene inizializzata con un delegato. Nella prima implementazione della classe Room, non ci sono guardie contro i delegati che generano eccezioni. Tali eccezioni saliranno alla proprietà North, in cui 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
}
}
Dato che preferirei non riuscire a creare l'oggetto piuttosto che leggere la proprietà North, cambio il costruttore in privato e introduco un metodo factory statico chiamato Create (). Questo metodo rileva 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 impuro il metodo Create ()?
Create
è anche impuro, perché lo chiama.
Create
funzione non ti protegge dall'ottenere un'eccezione quando ottieni la proprietà. Se il tuo delegato lancia, nella vita reale è molto probabile che venga lanciato solo in determinate condizioni. È probabile che le condizioni per il lancio non siano presenti durante la costruzione, ma sono presenti quando si ottiene la proprietà.