【问题标题】:How to create a generic extension method?如何创建通用扩展方法?
【发布时间】:2009-12-01 12:39:36
【问题描述】:

我想开发一个通用扩展方法,它应该按字母顺序排列字符串,然后按纵向升序排列。

我是说

string[] names = { "Jon", "Marc", "Joel",
                  "Thomas", "Copsey","Konrad","Andrew","Brian","Bill"};

var query = names.OrderBy(a => a.Length).ThenBy(a => a);

Generic Extension Method的开发方法是什么?

我试过了:

public static class ExtensionOperation
    {
        public static T[] AlphaLengthWise<T>(this T[] names)
        {
            var query = names.OrderBy(a => a.Length).ThenBy(a => a);
            return query;
        }
    }

我收到了:

错误 1:T 不包含 Length 的定义

错误 2:无法将 System.Linq.IOrderedEnumerable 转换为 T[]

【问题讨论】:

  • 拥有一个只适用于字符串的通用方法并没有多大意义......
  • 如果你只想排列字符串,为什么它应该是通用的?
  • @bniwredyc 因为generic 听起来很酷! :)
  • 您可能还想将ExtensionOperstion 更正为ExtensionOperation

标签: c# generics


【解决方案1】:

第一个错误是因为LengthString 类的属性,而在您的通用版本中,T 参数的类型未知。它可以是任何类型。

第二个错误是因为您只返回查询对象而不是实际结果。您可能需要在返回之前致电ToArray()

只需稍加修改,您就可以得出这样的结论:

public static class ExtensionOperation
{
    public static IEnumerable<T> AlphaLengthWise<T, L>(
        this IEnumerable<T> names, Func<T, L> lengthProvider)
    {
        return names
            .OrderBy(a => lengthProvider(a))
            .ThenBy(a => a);
    }
}

你可以这样使用:

string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" };
var result = names.AlphaLengthWise(a => a.Length);

【讨论】:

  • 我发现自己在泛型代码中经常使用lengthProvider 这样的技术。这只是我如此喜欢 lambdas 的另一个原因。 :D
【解决方案2】:

你为什么要这样做?只需使用

public static class ExtensionOperations
{
    public static IEnumerable<string> AlphaLengthWise(this string[] names)
    {
        var query = names.OrderBy(a => a.Length).ThenBy(a => a);
        return query;
    }
}

【讨论】:

  • 为什么是string[] 而不是IEnumerable&lt;String&gt;?您可以删除 .ToArray() 并将其推迟(如果我没记错的话)。
  • 这忽略了问题并提出了一个完全不同的问题的解决方案
【解决方案3】:

我认为您可能对泛型的用途有些困惑。

泛型是一种将类或方法定制为特定类型的方法。泛型方法或类被设计为适用于 any 类型。这在List&lt;T&gt; 类中最容易说明,可以将其定制为任何类型的列表。这为您提供了类型安全性,即知道列表仅包含该特定类型。

您的问题旨在处理特定类型,string 类型。泛型不会解决涉及特定类型的问题。

你想要的是一个简单的(非通用的)扩展方法:

public static class ExtensionOperations
{
    public static IEnumerable<string> AlphaLengthWise(
        this IEnumerable<string> names)
    {
        if(names == null)
            throw new ArgumentNullException("names");

        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
}

使参数和返回类型IEnumerable&lt;string&gt; 使其成为非泛型扩展方法,可以应用于任何实现IEnumerable&lt;string&gt; 的类型。这将包括string[]List&lt;string&gt;ICollection&lt;string&gt;IQueryable&lt;string&gt; 等等。

【讨论】:

    【解决方案4】:

    我想开发一个通用扩展方法,它应该按字母顺序排列 字符串 ...

    public static class ExtensionOperation
    {
        public static IEnumerable<String> AplhaLengthWise(
                                       this IEnumerable<String> names)
        {
            return names.OrderBy(a => a.Length).ThenBy(a => a);
        }
    }
    

    【讨论】:

      【解决方案5】:

      复制微软的做法:

      public static class ExtensionOperation {
          // Handles anything queryable.
          public static IOrderedQueryable<string> AlphaLengthWise(this IQueryable<string> names) {
              return names.OrderBy(a => a.Length).ThenBy(a => a);
          }
          // Fallback method for non-queryable collections.
          public static IOrderedEnumerable<string> AlphaLengthWise(this IEnumerable<string> names) {
              return names.OrderBy(a => a.Length).ThenBy(a => a);
          }
      }
      

      【讨论】:

        【解决方案6】:

        您想使用IEnumerable&lt;T&gt; 而不是T[]。除此之外,您将无法使用LengthT,因为并非所有类型都有Length 属性。您可以将扩展方法修改为.OrderBy(a =&gt; a.ToString().Length)

        如果您知道您将始终处理字符串,请使用IEnumerable&lt;String&gt; 而不是IEnumerable&lt;T&gt;,您将能够立即访问Length 属性。

        【讨论】:

        • 将 T[] 更改为 IEnumerable 不会要求元素的 Length 属性。
        • 肯定不会。这部分答案与第二个错误有关。 IOrderedEnumerable&lt;T&gt; 实现了IEnumerable&lt;T&gt;,这样就可以解决这部分问题。至于Length 属性,我的建议是ToString() 用于确保字符串,或者,如果他是新人,他总是在处理字符串,将T 更改为string
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-19
        • 2011-06-26
        • 1970-01-01
        • 2020-07-08
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        相关资源
        最近更新 更多