The following code examples provide context to my question.
The Room class is initialized with a delegate. In the first implementation of the Room class, there are no guards against delegates that throw exceptions. Such exceptions will bubble up to the North property, where the delegate is evaluated (note: the Main() method demonstrates how a Room instance is used in client code):
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
}
}
Being that I'd rather fail upon object creation rather than when reading the North property, I change the constructor to private, and introduce a static factory method named Create(). This method catches the exception thrown by the delegate, and throws a wrapper exception, having a meaningful exception message:
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;
}
}
Does the try-catch block render the Create() method impure?
Create
is also impure, because it calls it.Create
function does not protect you from getting an exception when getting the property. If your delegate throws, in real life it is very likely that it will thrown only under some conditions. Chances are that the conditions for throwing are not present during construction, but they are present when getting the property.