2016-11-12 84 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實現,在這裏表明,該方法是抽象的。在我能找到的所有實現中,具體實現。