【问题标题】:Can extension methods have generic parameters?扩展方法可以有泛型参数吗?
【发布时间】:2011-01-24 21:47:02
【问题描述】:

扩展方法能否有发言权:列表作为参数之一?

public static IEnumerable<XElement> GetSequenceDescendants(this IEnumerable<XElement> elements, params List<XName> names)
        {
            //do something
        }

扩展方法可以具有的参数类型是否有任何限制?

【问题讨论】:

  • 大多数扩展方法都有泛型参数。
  • 如果您从扩展方法声明中取出参数,您的代码可以编译。如果您不想从扩展方法中取出参数,则需要将 List 更改为 XName[]
  • 你真的问了两个问题,因为第一个 List 不能单独作为参数,你需要将它定义为像“params XName [] names”这样的数组,除非你制作 Lists 的 param 数组.

标签: c# linq generics linq-to-xml extension-methods


【解决方案1】:

简短的回答是扩展方法只是一个公共静态方法,可以像第一个参数的实例方法一样访问(感谢this关键字)。这意味着您可以使用可以在任何静态方法中使用的相同参数。

但是,如果您希望参数实际上是通用的,则需要将方法更改为:

public static IEnumerable<TElement> GetSequenceDescendants<TElement, TName>(this IEnumerable<TElement> elements, List<TName> names)
{
    //do something
}

您必须在方法定义中指定所有通用参数。

此外,您不能将 params 关键字与数组以外的任何内容一起使用,即 params TName[] 可以,但 params List&lt;TName&gt; 不行。

【讨论】:

  • &lt;XElement, XName&gt; 不需要是方法签名的一部分。这些不是该方法的类型参数。如果是IEnumerable&lt;T&gt;List&lt;U&gt;,那就另当别论了。
  • 不完全正确:您可以在扩展方法中使用T[] params。请参阅我在回答中引用的问题中的最佳答案 (In())。
  • 我没有说你不能在扩展方法中使用参数。我说你只能将它与数组一起使用。即 params T[] 可以,但 params List 不是。我已经在我的回答中澄清了它,以防其他人误解它。
  • 请注意,通过您的编辑,您已使方法本身具有通用性,我不相信是问题所在(尽管它可能是,而且不一定是坏事主意)。如果 OP 希望该方法专门处理 XElementXName 类,则需要将其更改回其原始签名的修改版本。
  • @Anthony Pegram:同意。很难准确说出所问的内容。
【解决方案2】:

类型推断是有限制的(比如编译器可以从参数中猜测泛型类型。扩展方法少了一个限制:您可以“取消引用”空指针(您可以编写和扩展方法bool IsNullorEmpty(this string) 和在空字符串上使用它。

例如:Linq 充满了很好的泛型扩展方法,您可以在这个问题中看到很多很棒的示例(巧妙地使用泛型):

What are your favorite extension methods for C#? (codeplex.com/extensionoverflow)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多