سؤال

First, I do not consider this question be the dup of these SO questions:

Should I always return IEnumerable<T> instead of IList<T>? and IEnumerable<T> as return type

As we all know ont of the main purposes of introducing several tiers is to decrease coupling.
We must define some interface for data access and our BL should not care about the details of DAL implementation. If mentioned interface returnes IEnumerable<T> BL does not know whether it is just a static IEnumerable or something that has deferred execution. At the same time this particular detail can affect perfromance considerably and requires different coding depending on the implementation.
Well, it is possible to call .ToList() for each IEnumerable in situations when we are going to iterate collection several times. But this decreases perfromance for static collections because of unnecessary new list instantiation.

So I'm trying to understand which approach is better.
More universal and potentially less performant vs More coupled-more performant. I guess, there's no silver bullet but it could be other approaches I've missed.

هل كانت مفيدة؟

المحلول 2

If it's important, conceptually, for the caller to know that the return type of the method is a List and not an IEnumerable (for example, to know that there will be no negative consequences for iterating it multiple times), then you should return a List. The point of returning the interface instead is a way of saying, "It doesn't matter what the implementation is." If the implementation does matter, then don't use the interface (in that specific situation).

نصائح أخرى

So I'm trying to understand which approach is better: more universal and less performant vs more coupled and more performant.

First, though that is an interesting tradeoff, in this case I would think that the relevant tradeoff is actually correct vs incorrect, which surely trumps any question of performance. A deferred-execution query usually has the property that it gives you the most up to date results of the query, whereas calling ToList gives you a snapshot of a past version of the query results. There are surely cases where one is correct and the other is incorrect.

Second, assuming that you have dealt with the correctness issue and really do have a performance tradeoff to make, the tradeoff you actually want to make is: more universal and unacceptable performance vs more coupled and acceptable performance, at which is becomes clear that you have to choose the one with acceptable performance.

If both have acceptable performance and one is a few nanoseconds slower than the other, or consumes a few bytes more memory than the other, and both are correct, then who cares which one you choose? Spend your valuable time thinking about something else. And if neither have acceptable performance then you have a bigger problem to solve.

I found good solution: All return types (the in interfaces) in DAL can't be IEnumerable<> (or can't be interface type). But it possible to use in BL. It can be architector's decision.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top