Hoe maak je een generieke extensiemethode aan?

Ik wil een generieke extensiemethode ontwikkelen die de string in alfabetische volgorde moet rangschikken en vervolgens in oplopende volgorde in de lengte.

Ik bedoel

string[] names = { "Jon", "Marc", "Joel",
                  "Thomas", "Copsey","Konrad","Andrew","Brian","Bill"};
var query = names.OrderBy(a => a.Length).ThenBy(a => a);

Wat is de manier om Generic Extension Method te ontwikkelen?

Ik heb geprobeerd:

public static class ExtensionOperation
    {
        public static T[] AlphaLengthWise<T>(this T[] names)
        {
            var query = names.OrderBy(a => a.Length).ThenBy(a => a);
            return query;
        }
    }

Ik heb ontvangen:

Fout 1: T bevat geen definitie voor Lengte

Fout 2: kan System.Linq.IOrderedEnumerableniet converteren naar T[].


Antwoord 1, autoriteit 100%

De eerste fout is omdat Lengtheen eigenschap is van de klasse string, terwijl in uw generieke versie het type T-parameter niet bekend is. Het kan elk type zijn.

De tweede fout is dat u alleen het query-object retourneert, maar niet het werkelijke resultaat. Mogelijk moet u ToArray()aanroepen voordat u terugkeert.

Met kleine aanpassingen zou je dit kunnen bedenken:

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

Die je zo zou kunnen gebruiken:

string[] names = { "Jon", "Marc", "Joel", "Thomas", "Copsey", "Konrad", "Andrew", "Brian", "Bill" };
var result = names.AlphaLengthWise(a => a.Length);

Antwoord 2, autoriteit 12%

Waarom wil je dit in het algemeen doen? Gebruik gewoon

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

Antwoord 3, autoriteit 7%

Ik denk dat je een beetje in de war bent over het doel van generieke geneesmiddelen.

Generieken zijn een manier om een ​​klasse of methode aan te passen aan een specifiek type. Een generieke methode of klasse is ontworpen om voor elktype te werken. Dit wordt het gemakkelijkst geïllustreerd in de klasse List<T>, waar het kan worden aangepast om een ​​lijst van elk type te zijn. Dit geeft u de typeveiligheid om te weten dat de lijst alleen dat specifieke type bevat.

Uw probleem is ontworpen om te werken aan een specifiek type, het type string. Generiek zal een probleem met een specifiek type niet oplossen.

Wat u zoekt is een eenvoudige (niet-generieke) extensiemethode:

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

Door het argument en het retourtype IEnumerable<String>te maken, wordt dit een niet-generieke extensiemethode die van toepassing kan zijn op elk type dat IEnumerable<String>implementeert. Dit omvat string[], List<string>, ICollection<string>, IQueryable<string>en nog veel meer.


Antwoord 4, autoriteit 2%

Ik wil een Generic Extension Method ontwikkelen die de stringsin alfabetische volgorde moet rangschikken en dan …

public static class ExtensionOperation
{
    public static IEnumerable<String> AplhaLengthWise(
                                   this IEnumerable<String> names)
    {
        return names.OrderBy(a => a.Length).ThenBy(a => a);
    }
}

Antwoord 5

Kopieer hoe Microsoft het doet:

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

Antwoord 6

U wilt IEnumerable<T>gebruiken in plaats van T[]. Verder kun je Lengthof Tniet gebruiken, aangezien niet alle typen een eigenschap Lengthhebben. U kunt uw extensiemethode wijzigen in .OrderBy(a => a.ToString().Length)

Als je weet dat je altijd met strings te maken hebt, gebruik dan IEnumerable<String>in plaats van IEnumerable<T>, en je hebt toegang tot de Lengtheigenschap onmiddellijk.

Other episodes