web-dev-qa-db-fra.com

Comment créer une méthode d'extension générique?

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

63
user215675

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);
94
Darin Dimitrov

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;
    }
}
14
Maximilian Mayerl

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.

7
Paul Turner

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

Cela ne fonctionnera que lorsque Ta une propriété Length, et vous aurez besoin d'une interface pour l'appliquer.

De plus, T doit être IComparable.

4
Henk Holterman

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);
    }
}
2
Alex Bagnolini

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);
    }
}
1
Christian Hayter

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.

0
David Hedlund