2009-12-01 21 views
55

Desidero sviluppare un metodo di estensione generico che dovrebbe disporre la stringa in ordine alfabetico quindi in senso ascendente in senso longitudinale.Come creare un metodo di estensione generico?

intendo

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

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

Qual è il modo di sviluppare Metodo di estensione generico?

ho provato:

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

che ho ricevuto:

di errore 1: T non contiene definizione per Lunghezza

Errore 2: non è possibile convertire System.Linq.IOrderedEnumerable-T[].

+4

Perché dovrebbe essere generico se si desidera disporre solo le stringhe? – bniwredyc

+6

@bniwredyc Perché 'generic' sembra fantastico! :) –

+0

Grazie mille a tutti – user215675

risposta

80

Il primo errore è dovuto al fatto Length è una proprietà della classe String mentre nella vostra versione generica del tipo del parametro T non è noto. Potrebbe essere di qualsiasi tipo

Il secondo errore è perché ritorni solo l'oggetto query, ma non il risultato effettivo. Potrebbe essere necessario chiamare ToArray() prima di tornare.

Con piccole modifiche si potrebbe trovare con questo:

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

che si poteva usare in questo modo:

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

Mi trovo utilizzando tecniche come questo 'lengthProvider' molto con codice generico. E 'solo una ragione in più per cui amo tanto lambda. : D –

-1

si desidera utilizzare IEnumerable<T> invece di T[]. A parte questo, non sarai in grado di utilizzare Length di T, poiché non tutti i tipi ha una proprietà Length. Si potrebbe modificare il vostro metodo di estensione per .OrderBy(a => a.ToString().Length)

Se sai che sarai sempre a che fare con le stringhe, utilizzare IEnumerable<String> piuttosto che IEnumerable<T>, e sarete in grado di accedere immediatamente alla proprietà Length.

+0

La modifica di T [] in IEnumerable non richiede la proprietà Length per gli elementi. –

+0

sicuramente no. quella parte della risposta riguardava il secondo errore. 'IOrderedEnumerable ' implementa 'IEnumerable ', in modo da risolvere quella parte del problema. Per quanto riguarda la proprietà 'Length', il mio suggerimento era che' ToString() 'fosse usato per assicurare una stringa, o, se lui nuovo avesse sempre a che fare con le stringhe, per cambiare' T' in 'stringa'. –

14

Perché vuoi farlo genericamente? Basta usare

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

Perché 'string []' e non 'IEnumerable '? È possibile rimuovere '.ToArray()' e lasciarlo differito (se non mi sbaglio). –

2

voglio sviluppare un metodo di estensione generico che dovrebbe organizzare le corde in alfabetico poi ...

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

Perché vuoi che sia generica?

questo funziona solo quando T ha una proprietà Length, e avrete bisogno di un interfaccia per far rispettare questo.

Inoltre T deve essere IComparable.

1

Copia come Microsoft fa:

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

penso si può essere un po 'confuso allo scopo di farmaci generici.

I generici sono un modo per adattare una classe o un metodo a un tipo specifico. Un metodo o una classe generici è progettato per funzionare con qualsiasi tipo. Questo è più facilmente illustrato nella classe List<T>, dove può essere adattato per essere un elenco di qualsiasi tipo. Questo ti dà la sicurezza del tipo di sapere che l'elenco contiene solo quel tipo specifico.

Il problema è stato progettato per funzionare su un tipo specifico, il tipo string. I generici non risolveranno un problema che riguarda un tipo specifico.

quello che vuoi è una semplice (non generica) Metodo di estensione:

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

Rendere l'argomento e il tipo restituito IEnumerable<string> rende questo un metodo di estensione non generica che può applicare a qualsiasi tipo di attuazione IEnumerable<string>. Ciò includerà string[], List<string>, ICollection<string>, IQueryable<string> e molti altri.

Problemi correlati