为什么Enumerable中的方法可以没有方法体

本文关键字:有方法 方法 Enumerable 为什么 | 更新日期: 2023-09-27 18:17:29

我被这个问题弄糊涂了。传统上,如果我这样写一个方法:

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

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

ExtentionMethods.MyClass。myMethod(int, System.Func)'必须声明一个主体,因为它没有标记为abstract, extern或partial

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

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

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

原因是什么?

为什么Enumerable中的方法可以没有方法体

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

只能在接口和抽象类中编写没有主体的方法。但是如果你想使用它,你需要在派生类中实现它们。

关于抽象方法的更多信息:MSDN抽象方法和接口:interface (c# Reference)

我查看了命名空间系统下的Enumerable类。Linq,我发现所有方法都没有方法体

你没有说你在看什么实现,但至少对CoreFX来说,这不是真的。System.Linq.Enumerable.Where的实现就在您所期望的src/System.Linq/src/System/Linq/Where.cs中:

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.Core项目的System/Linq/Enumerable.cs中:

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

在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实现,你所展示的方法是抽象的。在我能找到的所有实现中,它都是具体实现的。

Konstantin Zadiran已经告诉你你可能在看什么,元数据。

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