adam0101
adam0101

Reputation: 31055

Is there a built-in C# type that allows deferred execution, but not casting back to IQueryable?

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)

Upvotes: 0

Views: 191

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205749

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).

Upvotes: 4

Ronan Thibaudau
Ronan Thibaudau

Reputation: 3603

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;
        }
    }
}
}

Upvotes: 3

Related Questions