简体   繁体   English

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

[英]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? 在C#中是否有推荐的内置类型,可以将集合转换/广播到该内置类型,该类型仍将允许延迟执行,但不允许将该类型强制转换回IQueryable? (Like IEnumerable<T> can in some cases) (在某些情况下,例如IEnumerable<T>可以)

The "built in" way to guard IQueryable<T> would be Enumerable.Select like this 保护IQueryable<T>的“内置”方式将是Enumerable.Select这样的

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

AsEnumerable is not enough because it is a simply cast. AsEnumerable是不够的,因为它只是简单的强制转换。 But it's needed to ensure Enumerable.Select is used instead of Queryable.Select . 但是需要确保使用Enumerable.Select而不是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). 但是,除了“内置”之外,我看不到这种方法的好处,而是喜欢像另一个答案中那样使用自定义扩展方法,尽管这可以用作实现而不是迭代器函数(这也没有好处,但是有一个缺点)由于不必要的委托调用,因此确实可以使用自定义迭代器函数)。

A built in type no but it's pretty easy to do : 内置类型no,但是很容易做到:

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. 这样,您就不会返回强制转换的IQueryable(可以将其强制转换),而是创建一个新的IEnumerable对其进行包装,甚至根本不需要一个新类型,因为最终得到的IEnumerable本身将枚举可以枚举,但不公开。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM