如何创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[]
。
第一个错误是因为Length
是String
类的一个属性,而在通用版本中,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, string
types上工作。 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
属性。