2016-11-12 83 views
1

我被这个问题搞糊涂了。传统上,如果我写这样的方法:为什么Enumerable中的方法可能没有方法体?

public static class MyClass 
{ 
    public static int myMethod(this int x, Func<int, bool> evaluate); 
} 

我会得到一个编译错误,说:

'ExtentionMethods.MyClass.myMethod(INT,System.Func)' 必须声明主体因为它没有标出抽象,外部或部分

这是可以理解的。但是我看到名字空间System.Linq下的Enumerable类。我发现所有的方法都没有方法体,例如:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate); 

而且没有任何编译错误吧。为什么?

是什么原因?

+0

您发布的第二行代码无法编译并产生与第一个代码完全相同的错误...您确定实际尝试编译该代码(而不是查看某些已反编译的代码或文档) ? –

+2

你看着错误的文件。这是一个*引用程序集*,而不是在运行时实际使用的程序集。或者当您使用GoTo Definition命令时,您可能会在VS中获得虚假的反编译元数据。 .NET 4引用程序集仅在编译时使用,仅包含声明,主体为空。运行时程序集从GAC中检索。一定要看看这些,你可以随意导航c:\ windows \ microsoft.net \ assembly。或者使用[Reference Source](https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,577032c8811e20d3)。 –

回答

4

这是因为你看了元数据。元数据只是描述接口,而不是实现。

你可以只在接口和抽象类中写入没有主体的方法。但是如果你想使用它,你需要在派生类中实现它们。 MSDN abstract methods 和接口:interface (C# Reference)

1

康斯坦丁Zadiran已经告诉你什么你可能看,元数据大约抽象方法

更多信息。

没有身体的方法本质上是一种抽象方法(当然,您还必须添加abstract关键字来将其标记为一个)。只有抽象类和接口可以包含抽象方法。部分方法是另一种没有身体的方法。

2

我下的命名空间System.Linq的看着枚举类,我发现所有的方法都没有方法体

你没有说你在找什么实现,但至少CoreFX,它是不对。

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) 
{ 
    if (source == null) 
    { 
     throw Error.ArgumentNull(nameof(source)); 
    } 

    if (predicate == null) 
    { 
     throw Error.ArgumentNull(nameof(predicate)); 
    } 

    Iterator<TSource> iterator = source as Iterator<TSource>; 
    if (iterator != null) 
    { 
     return iterator.Where(predicate); 
    } 

    TSource[] array = source as TSource[]; 
    if (array != null) 
    { 
     return new WhereArrayIterator<TSource>(array, predicate); 
    } 

    List<TSource> list = source as List<TSource>; 
    if (list != null) 
    { 
     return new WhereListIterator<TSource>(list, predicate); 
    } 

    return new WhereEnumerableIterator<TSource>(source, predicate); 
} 

在Microsoft .NET参考源,它是在System/Linq/Enumerable.csSystem.Core项目:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if (source == null) throw Error.ArgumentNull("source"); 
    if (predicate == null) throw Error.ArgumentNull("predicate"); 
    if (source is Iterator<TSource>) return ((Iterator<TSource>)source).Where(predicate); 
    if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate); 
    if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate); 
    return new WhereEnumerableIterator<TSource>(source, predicate); 
} 
,你会想到吧,在 src/System.Linq/src/System/Linq/Where.csSystem.Linq.Enumerable.Where的实现是正确的

在Mono中,执行过程在mcs/class/System.Core/System.Linq/Enumerable.cs之前,它们切换高等教育委员会从微软的开源实现:

public static IEnumerable<TSource> Where<TSource> (this IEnumerable<TSource> source, Func<TSource, bool> predicate) 
{ 
    Check.SourceAndPredicate (source, predicate); 

    // It cannot be IList<TSource> because it may break on user implementation 
    var array = source as TSource[]; 
    if (array != null) 
     return CreateWhereIterator (array, predicate); 

    return CreateWhereIterator (source, predicate); 
} 

我无法找到一个单一的.NET实现,在这里表明,该方法是抽象的。在我能找到的所有实现中,具体实现。