C# 如何创建通用扩展方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1825952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:10:46  来源:igfitidea点击:

How to create a generic extension method?

c#generics

提问by user215675

I want to develop a Generic Extension Method which should arrange the string in alphabetical then by lengthwise ascending order.

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

I mean

我的意思是

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

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

What is the way to develop Generic Extension Method?

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

I tried :

我试过 :

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

I received :

我收到了 :

Error 1: T does not contain definition for Length

Error 2: can not convert System.Linq.IOrderedEnumerableto T[].

错误 1:T 不包含长度的定义

错误 2:无法转换System.Linq.IOrderedEnumerableT[].

采纳答案by Darin Dimitrov

The first error is because Lengthis a property of the Stringclass while in your generic version the type of the T parameter is not known. It could be any type.

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

The second error is because you return just the query object but not the actual result. You might need to call ToArray()before returning.

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

With little modifications you could come up with this:

只需稍作修改,您就可以想出这个:

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);
    }
}

Which you could use like this:

你可以这样使用:

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

回答by dxh

You want to use IEnumerable<T>instead of T[]. Other than that, you won't be able to use Lengthof T, since not all types has a Lengthproperty. You could modify your extension method to .OrderBy(a => a.ToString().Length)

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

If you know you'll always be dealing with strings, use IEnumerable<String>rather than IEnumerable<T>, and you'll be able to access the Lengthproperty immediately.

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

回答by Maximilian Mayerl

Why do you want to do this generically? Just use

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

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

回答by Alex Bagnolini

I want to develop a Generic Extension Method which should arrange the stringsin alphabetical then ...

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

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

回答by Christian Hayter

Copy how Microsoft does it:

复制微软的做法:

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);
    }
}

回答by Paul Turner

I think you may be a little confused to the purpose of generics.

我想你可能对泛型的目的有点困惑。

Generics are a way to tailor a class or method to a specific type. A generic method or class is designed to work for anytype. This is most easily illustrated in the List<T>class, where it can be tailored to be a list of any type. This gives you the type-safety of knowing the list only contains that specific type.

泛型是一种为特定类型定制类或方法的方法。泛型方法或类旨在适用于任何类型。这在List<T>类中最容易说明,可以将其裁剪为任何类型的列表。这为您提供了知道列表仅包含该特定类型的类型安全性。

Your problem is designed to work on a specific type, the stringtype. Generics are not going to solve a problem which involves a specific type.

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

What you want is a simple (non-generic) Extension Method:

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

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);
    }
}

Making the argument and the return type IEnumerable<string>makes this a non-generic extension method which can apply to any type implementing IEnumerable<string>. This will include string[], List<string>, ICollection<string>, IQueryable<string>and many more.

使参数和返回类型IEnumerable<string>成为一个非泛型扩展方法,可以应用于任何实现IEnumerable<string>. 这将包括string[]List<string>ICollection<string>IQueryable<string>等等。