Je veux développer une méthode d'extension générique qui devrait organiser la chaîne par ordre alphabétique puis longitudinal.
Je veux dire
string[] names = { "Jon", "Marc", "Joel",
"Thomas", "Copsey","Konrad","Andrew","Brian","Bill"};
var query = names.OrderBy(a => a.Length).ThenBy(a => a);
Comment développer la méthode d'extension générique?
J'ai essayé :
public static class ExtensionOperation
{
public static T[] AlphaLengthWise<T>(this T[] names)
{
var query = names.OrderBy(a => a.Length).ThenBy(a => a);
return query;
}
}
J'ai reçu :
Erreur 1: T ne contient pas de définition pour la longueur
Erreur 2: impossible de convertir
System.Linq.IOrderedEnumerable
àT[]
.
La première erreur est due au fait que Length
est une propriété de la classe String
alors que dans votre version générique le type du paramètre T n'est pas connu. Ce pourrait être n'importe quel type.
La deuxième erreur est due au fait que vous renvoyez uniquement l'objet de requête, mais pas le résultat réel. Vous devrez peut-être appeler ToArray()
avant de revenir.
Avec de petites modifications, vous pourriez trouver ceci:
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);
}
}
Que vous pourriez utiliser comme ceci:
string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" };
var result = names.AlphaLengthWise(a => a.Length);
Pourquoi voulez-vous faire cela de manière générique? Utilisez simplement
public static class ExtensionOperations
{
public static IEnumerable<string> AlphaLengthWise(this string[] names)
{
var query = names.OrderBy(a => a.Length).ThenBy(a => a);
return query;
}
}
Je pense que vous pouvez être un peu confus quant à l'objectif des génériques.
Les génériques sont un moyen d'adapter une classe ou une méthode à un type spécifique. Une méthode ou une classe générique est conçue pour fonctionner avec le type any. Ceci est plus facilement illustré dans le List<T>
classe, où elle peut être adaptée pour être une liste de tout type. Cela vous donne la sécurité de type de savoir que la liste ne contient que ce type spécifique.
Votre problème est conçu pour fonctionner sur un type spécifique, le type string
. Les génériques ne vont pas résoudre un problème impliquant un type spécifique.
Ce que vous voulez, c'est une méthode d'extension simple (non générique):
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);
}
}
Création de l'argument et du type de retour IEnumerable<string>
en fait une méthode d'extension non générique qui peut s'appliquer à tout type implémentant IEnumerable<string>
. Cela comprendra string[]
, List<string>
, ICollection<string>
, IQueryable<string>
et beaucoup plus.
Pourquoi voulez-vous qu'il soit générique?
Cela ne fonctionnera que lorsque T
a une propriété Length, et vous aurez besoin d'une interface pour l'appliquer.
De plus, T doit être IComparable.
Je veux développer une méthode d'extension générique qui devrait organiser les chaînes en ordre alphabétique puis ...
public static class ExtensionOperation
{
public static IEnumerable<String> AplhaLengthWise(
this IEnumerable<String> names)
{
return names.OrderBy(a => a.Length).ThenBy(a => a);
}
}
Copiez comment Microsoft le fait:
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);
}
}
Vous souhaitez utiliser IEnumerable<T>
Au lieu de T[]
. En dehors de cela, vous ne pourrez pas utiliser Length
de T
, car tous les types n'ont pas de propriété Length
. Vous pouvez modifier votre méthode d'extension en .OrderBy(a => a.ToString().Length)
Si vous savez que vous aurez toujours affaire à des chaînes, utilisez IEnumerable<String>
Plutôt que IEnumerable<T>
, Et vous pourrez accéder immédiatement à la propriété Length
.