如何创build一个通用的扩展方法?

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

我的意思是

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[]

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

第二个错误是因为你只返回查询对象而不是实际的结果。 您可能需要在返回之前调用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); 

为什么你想这样做一般? 只是使用

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

我想你可能会对generics的目的有些困惑。

generics是根据特定types定制类或方法的一种方法。 generics方法或类被devise为适用于任何types。 这在List<T>类中很容易说明,它可以被定制为任何types的列表。 这让你知道该列表的types安全性只包含该特定types。

你的问题被devise为在一个特定的types, stringtypes上工作。 generics不会解决涉及特定types的问题。

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

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

使参数和返回typesIEnumerable<string>使得这是一个非generics扩展方法,可以应用于任何实现IEnumerable<string>types。 这将包括string[]List<string>ICollection<string>IQueryable<string>等等。

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

这只会在T有一个Length属性时才起作用,而且你需要一个接口来执行。

此外T必须是IComparable。

我想开发一个通用扩展方法,应按字母顺序排列string ,然后…

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

复制微软如何做到这一点:

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

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

如果您知道总是处理string,请使用IEnumerable<String>而不是IEnumerable<T> ,您将能够立即访问Length属性。