2014-04-19 41 views
2

所以我想我並不真正瞭解上述情況。就像假設你有上枚舉類型,像這樣的擴展....擴展通用參數與Func參數通用參數之間的關係

public static TElement StringMatch<TElement, TData>(
     this IEnumerable<TElement> source, 
     Func<TElement, TData> selector) 

一切都是在這裏很好,但我一直在假設StringMatch泛型參數反映Func鍵泛型參數,因爲Func<>是什麼對用戶來說似乎通過了。

但說我要到指定的Func<>返回類型是一個特定的參數,也許像Func<TElement, string>

現在我的想法是改變簽名是這樣的...

public static TElement StringMatch<TElement, string>(
      this IEnumerable<TElement> source, 
      Func<TElement, string> selector) 

。 ..again,以反映通過Func <>。但是,如果我嘗試調用這個東西就像Books.StringMatch(b => b.Title),我得到了如下的錯誤...

'Book' does not contain a definition for 'StringMatch' and no extension method 'StringMatch' accepting a first argument of type 'Book' could be found (are you missing a using directive or an assembly reference?) 

那麼,這裏的交易?什麼正好做擴展方法指定的通用參數?

+0

由於您要求編譯器查找名爲「TData」的類型,因此您的第二個簽名將不會編譯。由於您沒有將其包含在泛型方法定義中,因此編譯器不知道TData應該是泛型類型參數。也許我真的錯過了一些東西,但是你可能會詳細說明你想要StringMatch做什麼? – Vincent

+0

哎呀,這實際上是一個錯誤,現在編輯... – MassStrike

回答

3

一旦你有

public static TElement StringMatch<TElement, TData>(
    this IEnumerable<TElement> source, 
    Func<TElement, TData> selector) 

它覆蓋了調用者傳遞一個Func其中TDatastring的情況。

如果你想TData永遠是特定類型string然後簡單地去除作爲方法的正式泛型參數:

public static TElement StringMatch<TElement>(
    this IEnumerable<TElement> source, 
    Func<TElement, string> selector) 

你可以,當然,實現這兩個。編譯器將選擇最具體的一個。調用者也可以明確指定類型參數,只留下一個選項。

+0

好的,我認爲這是有道理的。因此,擴展方法的泛型參數只包含該方法參數中包含的所有泛型參數,不包括您要擴展的枚舉?我認爲令我困惑的是泛型參數和Func參數使用相同的語法,因爲2 Func參數,我認爲*有*爲2個通用參數。 – MassStrike

+2

方法或委託名稱後面的參數是形式參數聲明。 (它們也可以在類/接口聲明中的類/接口名稱之後)。其他任何地方都是對這些的引用。它們可用於返回類型,參數類型或使用類型的主體中的任何位置。 (他們甚至可以不用。) –