Is there a recommended built-in type in C# that collections can be converted/cast to that will still allow deferred execution, but not allow the type to be cast back into IQueryable? (Like IEnumerable<T>
can in some cases)

- 29,096
- 21
- 96
- 174
-
I don't know of a built-in one, but since it can be two lines of code in one function, why not do it yourself? – Dark Falcon Jan 18 '16 at 23:58
-
You should have a look at the yield return statement. – Thomas Jan 18 '16 at 23:59
2 Answers
The "built in" way to guard IQueryable<T>
would be Enumerable.Select
like this
IQueryable<T> source = ...;
var result = source.AsEnumerable().Select(x => x);
AsEnumerable
is not enough because it is a simply cast. But it's needed to ensure Enumerable.Select
is used instead of Queryable.Select
.
However, other than being "built in", I see no benefit of this approach and prefer the custom extension method like in another answer, although this can be used as implementation instead of iterator function (which also has no benefit, but rather a drawback due to unnecessary delegate call, so really the custom iterator function is the right way to go).

- 732,580
- 175
- 1,330
- 1,459

- 195,425
- 15
- 312
- 343
-
@M.kazemAkhgary You are welcome. And btw, glad to see you posting again! – Ivan Stoev Jan 19 '16 at 19:54
A built in type no but it's pretty easy to do :
public static class Utils
{
public static IEnumerable<T> AsDefferedEnumerable<T>(this IQueryable<T> Source)
{
foreach (var item in Source)
{
yield return item;
}
}
}
This way you're not returning a casted IQueryable (that could be casted back) but creating a new IEnumerable wrapping it , you don't even need a new type at all for that you just end up with an IEnumerable that will itself enumerate the IQueryable as it is enumerated without exposing it.
Edit : sample of a wrapper object (untested)
public class HideImplementationEnumerable<T>
{
public HideImplementationEnumerable(IEnumerable<T> Source)
{
this.Source = Source;
}
private IEnumerable<T> Source;
public IEnumerable<T> Value
{
get
{
foreach (var item in Source)
{
yield return item;
}
}
}
}

- 3,413
- 3
- 29
- 78
-
I like this approach, but my reason for wanting a different type was so a code reviewer could see at a glance that the return type is something that code downstream cannot alter the query with. – adam0101 Jan 19 '16 at 14:52
-
@adam0101 That sounds unecessary, if a code reviewer sees an IEnumerable all he should assume is that he can enumerate it, but changing this to a type is trivial, editing my answer now for a type version (a type also has other advantages, it is pretty useless to do "just that" but it can be extended to do caching etc.)* – Ronan Thibaudau Jan 19 '16 at 14:56