【问题标题】:How does OfType<T>() Work?OfType<T>() 是如何工作的?
【发布时间】:2010-05-14 11:23:21
【问题描述】:

OfType() 是如何工作的?

我阅读了this link 了解发生了什么,但 LINQ 提供程序究竟如何知道如何获取与指定类型匹配的所有对象。我知道IQueryable&lt;T&gt;“链接”请求,然后评估何时调用GetEnumerator()(对吗?)。

具体想知道框架是如何快速做类型比较的?我在 .NET 2.0 项目中编写了一个方法,如下所示(因为 2.0 不支持这些功能):

    public IEnumerable<TResult> OfType<TResult>()
        where TResult : class
    {
        foreach (TItem item in this.InnerList)
        {
            TResult matchItem = item as TResult;

            if (matchItem != null)
            {
                yield return matchItem;
            }
        }
    }

这是最好的实现吗?

编辑:我对这个OfType&lt;T&gt;() 的主要担心是它

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    您当前的实现(按设计)不支持值类型。

    如果您想要更接近 LINQ 的 OfType 方法的东西,它支持所有类型,那么试试这个:

    public IEnumerable<TResult> OfType<TResult>(IEnumerable source)
    {
        foreach (object item in source)
        {
            if (item is TResult)
                yield return (TResult)item;
        }
    }
    

    【讨论】:

    • 所以使用is 然后进行强制转换会更快,还是因为您包含值类型?我认为使用 as 然后检查 null 更快?
    • 由于特定的编译器优化,差异可能无关紧要。
    • @TheCloudlessSky:如果该方法仅限于处理 ref 类型,那么我将使用 as/test-for-null 组合,就像您已经完成的那样。使用is/cast 和as/test-for-null 之间的速度差异可以忽略不计,但如果这种级别的微优化对您很重要,那么我建议您进行一些基准测试。
    • @TheCloudlessSky:(如果减少几纳秒真的很关键,那么为什么要使用迭代器来产生IEnumerable&lt;T&gt; 序列,而不是一些更快、更接近金属的数据类型?)
    • @Surya:因为Where要求源序列是通用的IEnumerable&lt;T&gt;OfType 接受非泛型 IEnumerable 序列。
    【解决方案2】:

    在我看来这是一个很好的实现,但它看起来是特定于实现的(您指的是 this.InnerList)。如果您创建了一个扩展 IEnumerable 的扩展方法(不是 2.0 支持的吗?),您将能够在任何可枚举集合上使用它,不是吗?

    【讨论】:

    • InnerList 实际上是一个'List'。同样在工作中我们不能使用 VS2008(呃......)所以我们不能使用 3.5 编译器来定位 2.0。所以不,我不能使用扩展方法。
    猜你喜欢
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多