是否有内置的C#类型允许延迟执行,但不能转回IQueryable?

时间:2016-01-18 23:54:22

标签: c# generic-collections deferred-execution

C#中是否有一个推荐的内置类型可以转换/转换为仍然允许延迟执行的集合,但不允许将类型转换回IQueryable? (在某些情况下可以像IEnumerable<T>一样)

2 个答案:

答案 0 :(得分:4)

保护IQueryable<T>的“内置”方式将Enumerable.Select像这样

IQueryable<T> source = ...;
var result = source.AsEnumerable().Select(x => x); 

AsEnumerable是不够的,因为它是一个简单的演员。但需要确保使用Enumerable.Select代替Queryable.Select

然而,除了“内置”之外,我认为这种方法没有任何好处,并且更喜欢another answer中的自定义扩展方法,尽管这可以用作实现而不是迭代器函数(也没有好处,但是由于不必要的委托调用导致的缺点,所以真正的自定义迭代器函数是正确的方法)。

答案 1 :(得分:3)

内置类型没有,但它很容易做到:

public static class Utils
{
    public static IEnumerable<T> AsDefferedEnumerable<T>(this IQueryable<T> Source)
    {
        foreach (var item in Source)
        {
            yield return item;
        }
    }
}

这样你就不会返回一个转换的IQueryable(它可以被转换回来)但是创建一个新的IEnumerable包装它,你根本不需要一个新的类型,因为你最终会得到一个IEnumerable它本身枚举了IQueryable,因为它被枚举而不会暴露它。

编辑:包装器对象的样本(未经测试)

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