2014-04-19 43 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

方法或委托名称后面的参数是形式参数声明。 (它们也可以在类/接口声明中的类/接口名称之后)。其他任何地方都是对这些的引用。它们可用于返回类型,参数类型或使用类型的主体中的任何位置。 (他们甚至可以不用。) –