How to create a generic extension method?
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);
r开发者_如何学运维eturn query;
}
}
I received :
Error 1: T does not contain definition for Length
Error 2: can not convert
System.Linq.IOrderedEnumerable
toT[]
.
The first error is because Length
is a property of the String
class while in your generic version the type of the T parameter is not known. It could be any type.
The second error is because you return just the query object but not the actual result. You might need to call ToArray()
before returning.
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);
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;
}
}
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 any type. 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.
Your problem is designed to work on a specific type, the string
type. Generics are not going to solve a problem which involves a specific type.
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.
I want to develop a Generic Extension Method which should arrange the strings in alphabetical then ...
public static class ExtensionOperation
{
public static IEnumerable<String> AplhaLengthWise(
this IEnumerable<String> names)
{
return names.OrderBy(a => a.Length).ThenBy(a => a);
}
}
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);
}
}
You want to use IEnumerable<T>
instead of T[]
. Other than that, you won't be able to use Length
of T
, since not all types has a Length
property. You could modify your extension method to .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 Length
property immediately.
精彩评论