如何创建通用扩展方法?

时间:2009-12-01 12:39:36

标签: c# generics

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

我的意思是

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

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

开发通用扩展方法的方法是什么?

我试过了:

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不包含长度

的定义      

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

7 个答案:

答案 0 :(得分:94)

第一个错误是因为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);

答案 1 :(得分:15)

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

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

答案 2 :(得分:7)

我认为你可能会对仿制药的目的感到困惑。

泛型是一种为特定类型定制类或方法的方法。通用方法或类旨在用于任何类型。这在List<T>类中最容易说明,可以将其定制为任何类型的列表。这使您知道列表中只包含特定类型的类型安全。

您的问题旨在处理特定类型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<string>使这成为非泛型扩展方法,可以应用于实现IEnumerable<string>的任何类型。这将包括string[]List<string>ICollection<string>IQueryable<string>等等。

答案 3 :(得分:4)

为什么你希望它是通用的?

这仅在T具有Length属性时才有效,并且您需要一个接口来强制执行该属性。

此外,T必须是IC Comparable。

答案 4 :(得分:2)

  

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

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

答案 5 :(得分:1)

复制Microsoft的工作方式:

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 :(得分:0)

您想使用IEnumerable<T>代替T[]。除此之外,您将无法使用Length T,因为并非所有类型都具有Length属性。您可以将扩展方法修改为.OrderBy(a => a.ToString().Length)

如果您知道自己将始终处理字符串,请使用IEnumerable<String>而非IEnumerable<T>,并且您将能够立即访问Length媒体资源。