2009-12-01 5 views
55

Je veux développer une méthode d'extension générique qui devrait organiser la chaîne en ordre alphabétique puis par ordre croissant dans le sens de la longueur.Comment créer une méthode d'extension générique?

Je veux dire

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

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

Quelle est la façon de développer 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; 
     } 
    } 

Je reçus:

Erreur 1: T ne contient pas de définition Longueur

Erreur 2: ne peut pas convertir System.Linq.IOrderedEnumerable-T[].

+4

Pourquoi cela devrait-il être générique si vous voulez seulement organiser les chaînes? – bniwredyc

+6

@bniwredyc Parce que générique semble cool! :) –

+0

Merci beaucoup à tous – user215675

Répondre

80

La première erreur est parce que Length est une propriété de la classe String alors que dans votre version générique du type du paramètre T est pas connu. Cela pourrait être n'importe quel type.

La deuxième erreur est 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 peu de modifications que vous pouvez venir avec 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); 
+0

Je me trouve en utilisant beaucoup de techniques comme 'lengthProvider' avec du code générique. C'est juste une raison de plus d'aimer les lambdas. : D –

-1

Vous voulez 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 pour .OrderBy(a => a.ToString().Length)

Si vous savez que vous serez toujours affaire avec des cordes, utilisez IEnumerable<String> plutôt que IEnumerable<T>, et vous serez en mesure d'accéder immédiatement à la propriété Length.

+0

La modification de T [] en IEnumerable ne demandera pas de propriété Length pour les éléments. –

+0

c'est sûr. cette partie de la réponse était en ce qui concerne la deuxième erreur. 'IOrderedEnumerable ' implémente 'IEnumerable ', ce qui résoudrait cette partie du problème. En ce qui concerne la propriété 'Length', ma suggestion était que' ToString() 'soit utilisé pour assurer une chaîne, ou, s'il était nouveau il aurait toujours affaire à des chaînes, pour changer' T' en 'string'. –

14

Pourquoi voulez-vous le faire génériquement? Il suffit d'utiliser

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

Pourquoi 'string []' et non 'IEnumerable '? Vous pouvez supprimer le '.ToArray()' et le laisser différé (si je ne me trompe pas). –

2

Je veux développer une méthode d'extension générique qui devrait organiser les chaînes par 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); 
    } 
} 
3

Pourquoi voulez-vous qu'il soit générique?

Cela ne fonctionnera que si T a une propriété Length et vous aurez besoin d'une interface pour l'appliquer.

De plus, T doit être IComparable.

1

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

Je pense que vous pouvez être un peu confus à la fin des génériques. Les génériques permettent 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 pour n'importe quel type. Ceci est le plus facilement illustré dans la classe List<T>, où il peut être adapté pour être une liste de n'importe quel type. Cela vous donne le type de sécurité 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 qui implique un type spécifique.

Ce que vous voulez est un simple (non générique) Méthode d'extension:

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

Faire l'argument et le type de retour IEnumerable<string> rend cette méthode d'extension non-générique qui peut appliquer à tout type mettant en oeuvre IEnumerable<string>. Cela comprend string[], List<string>, ICollection<string>, IQueryable<string> et beaucoup plus.

Questions connexes