像.ToList()和.Reverse()这样的扩展方法如何看待封面?

时间:2012-08-10 16:36:15

标签: c# extension-methods

我使用了许多扩展方法,例如.ToList().Reverse()等,而没有真正考虑使用它们时真正发生的事情。我一直在google上搜索这些方法究竟是做什么的,但我似乎无法在任何地方找到它们。当我在visual studio中使用.toList()并点击" Go to definition"我只看到了

         // Summary:
        //     Creates a System.Collections.Generic.List<T> from an System.Collections.Generic.IEnumerable<T>.
        //
        // Parameters:
        //   source:
        //     The System.Collections.Generic.IEnumerable<T> to create a System.Collections.Generic.List<T>
        //     from.
        //
       ...etc

我试图找出(例如).Reverse();方法内部的内容。它是否使用堆栈,它只是做这样的事情......?

public static List<string> Reverse(List<string> oldList)
{
List<string> newList = new List<string>();    
for (int i = oldList.Count-1; i >= 0; i --)
    {
    newList.Add(oldList[i]);
    }
    return newList;
}

注意:我无法想象它实际上是这样的,但只是为了澄清我的问题。

是否有任何网站/图书/我可以查看的内容,以显示这些方法究竟是做什么的?

5 个答案:

答案 0 :(得分:4)

当您单击“转到定义”时,可以将Visual Studio配置为从Microsoft源服务器加载.Net Framework的源代码。以下是一些说明:http://referencesource.microsoft.com/downloadsetup.aspx

请注意,您不必下载大包,只需设置选项即可。

以下是ToList的源代码:

    public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) { 
        if (source == null) throw Error.ArgumentNull("source");
        return new List<TSource>(source); 
    } 

以下是Reverse的源代码:

    public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source"); 
        return ReverseIterator<TSource>(source);
    }

    static IEnumerable<TSource> ReverseIterator<TSource>(IEnumerable<TSource> source) { 
        Buffer<TSource> buffer = new Buffer<TSource>(source);
        for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i]; 
    } 

答案 1 :(得分:2)

.ToList()

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

.Reverse()在列表的基础数组上调用Array.Reverse

我通过反射器反编译找到了它,但您也可以查看the .NET source

答案 2 :(得分:1)

Jon Skeet(如果他没有在这里打败我)写了一篇很棒的(和很长的)series of blog posts,他(或多或少)将Linq重新实现为对象。您可以看到所有方法的实现(通常与库实现相同或类似),包括您在此处列出的方法。

Reverse的情况下,您的实现与库(和Jon的)实现之间的一个主要区别是执行不同。 Reverse不会枚举传递的IEnumerable的任何元素,直到它必须(在这种情况下,它是在请求第一个项目时)。我将这种差异的后果更深入地分析到博客系列。

答案 3 :(得分:1)

您可以使用dotPeek之类的工具来浏览代码。

答案 4 :(得分:1)

扩展方法只是一个普通的静态方法,但是您要扩展的类的对象作为参数传递给它。所以假设我们想要扩展内置类int以包含toString()方法(是的,我知道,它已经有一个)。语法如下所示:

public static string toString(this int myInt)
{
     return (string)myInt;
}

请注意参数的this关键字。这告诉编译器这是一个扩展方法。