【问题标题】:Relationship between extension generic parameters and Func argument generic parameters扩展泛型参数和 Func 实参泛型参数之间的关系
【发布时间】:2014-04-19 05:00:54
【问题描述】:

所以我想我不太了解上述内容。就像假设你有一个像这样的可枚举类型的扩展......

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

这里一切都很好,但我一直假设 StringMatch 泛型参数反映了 Func 泛型参数,因为 Func&lt;&gt; 是用户看来要传递的。

但是说我要指定Func&lt;&gt;的返回类型是一个具体的参数,可能像Func&lt;TElement, string&gt;

现在我的想法是像这样改变签名......

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

...再次,镜像传递的 Func。但是,如果我尝试在 Books.StringMatch(b =&gt; 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?) 

那么这里的交易是什么?扩展方法中的泛型参数究竟指定了什么?

【问题讨论】:

  • 您的第二个签名将无法编译,因为您要求编译器查找名为“TData”的类型。由于您没有将它包含在泛型方法定义中,因此编译器不知道 TData 应该是泛型类型参数。也许我真的错过了一些东西,但您能否详细说明您希望 StringMatch 做什么?
  • 糟糕,这实际上是一个错误,现在正在编辑...

标签: c# .net linq generics extension-methods


【解决方案1】:

一旦你拥有

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)

当然,您可以同时实现这两者。编译器将选择最具体的一个。调用者也可以显式指定类型参数,只留下一个选择。

【讨论】:

  • 好的,我认为这是有道理的。所以扩展方法的泛型参数只包括该方法的参数中包含的所有泛型参数,不包括您要扩展的枚举?我认为让我感到困惑的是泛型参数和 Func 参数使用相同的语法,我认为那里 必须 是 2 个泛型参数,因为有 2 个 Func 参数
  • 方法名或委托名后面的为形参声明。 (它们也可以在类/接口声明中的类/接口名称之后。)其他任何地方都是对它们的引用。它们可以用在返回类型、参数类型或正文中使用类型的任何地方。 (它们甚至可以不用。)
猜你喜欢
  • 1970-01-01
  • 2012-07-24
  • 2023-02-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
相关资源
最近更新 更多