I wish to project a collection from one type (Something) to another type (Someth
ID: 643487 • Letter: I
Question
I wish to project a collection from one type (Something) to another type (SomethingElse). Yes, this is a very open-eneded question, but which of the two options below do you prefer?
Creating a new instance using new:
var result = query.Select(something => new SomethingElse(something));
Using a factory:
var result = query.Select(something => SomethingElse.FromSomething(something));
When I think of a projection, I generally think of it as a conversion. Using new gives me this idea that I'm creating new objects during a conversion, which doesn't feel right. Semantically, SomethingElse.FromSomething() most definitely fits better. Although, the second option does require addition code to setup a factory, which could become unnecessarily compulsive.
Explanation / Answer
This question appears to be more about the appropriateness of using a factory method over a straight constructor call. My favorite example uses the TimeSpan type because it has several constructor overloads and several FromXXX static factory methods.
// how easily can you spot the bug?
int[] durationMs = { 1, 2, 3, 4 };
IEnumerable<TimeSpan> durations1 =
durationMs.Select(ms => new TimeSpan(0, 0, ms));
IEnumerable<TimeSpan> durations2 =
durationMs.Select(ms => TimeSpan.FromSeconds(ms));
Which expression was the bug easier to spot in the two equivalent projections? Fixing the two expressions is also interesting:
// spot the bug after the fix?
IEnumerable<TimeSpan> durations1 =
durationMs.Select(ms => new TimeSpan(0, 0, 0, ms));
IEnumerable<TimeSpan> durations2 =
durationMs.Select(ms => TimeSpan.FromMilliseconds(ms));
The durations2 expression is correct (bug fixed). However, adding just one 0 parameter to the durations1 constructor call was not enough - we have to add another 0 - going from the 3 parameter version to the 5 parameter version in order to specify milliseconds (as documented on msdn).
The "Framework Design Guidelines" book has some great advice on when to provide static factory methods. The book goes into more detail on each point whereas the link I provided merely summarizes the advice. Hope this helps.