2010-07-27 17 views
7

Quindi, sono un po 'fuori dalla mia zona di comfort quando si tratta di Func <>, Generics e lambda, ma penso di avere l'idea generale (sorta di) ma ancora un po' confusa.C# Func <> e generics

Ho implementato la classe SortableObservableCollection (tratto da on-line da qualche parte - grazie a chiunque fosse l'ho presa da!) Ed è utilizzata in questo modo:

_lookuplistViewModel.Sort(x => x.BrandName, ListSortDirection.Ascending); 

dove x è il tipo di oggetto implementato da la collezione ordinabile. In questo caso, BrandName è una proprietà del tipo di oggetto implementato, ma voglio usare il codice sopra in una classe generica e passare la proprietà su cui ordinare. Il metodo Sort assomiglia a questo:

public void Sort<TKey>(Func<T, TKey> keySelector, ListSortDirection direction) 
{ 
    switch (direction) 
    { 
    case ListSortDirection.Ascending: 
     { 
     ApplySort(Items.OrderBy(keySelector)); 
     break; 
     } 
    case System.ComponentModel.ListSortDirection.Descending: 
     { 
     ApplySort(Items.OrderByDescending(keySelector)); 
     break; 
     } 
    } 
} 

La classe generica su cui il metodo Sort viene chiamato è definita in questo modo:

public class ExtendedLookupManagerViewModel<VMod, Mod> : LookupManagerViewModel 
where VMod : ExtendedLookupViewModel 
where Mod : ExtendedLookupModelBase 

e mi piacerebbe creare un'istanza in questo modo:

_medProd = new ExtendedLookupManagerViewModel<MedicinalProductViewModel, MedicinalProduct>(string property); 

dove property è la proprietà su cui ordinare. Idealmente questo dovrebbe essere sicuro, ma una stringa sarà sufficiente.

Qualcuno può aiutarmi a orientarmi nella direzione giusta per favore?

+3

Sono abbastanza bene con lambda e generici, ma non riesco a capire cosa lo chiedi, la prima riga di codice che hai pubblicato fa quello che stai chiedendo dalla tua descrizione dei requisiti, ma il tuo sig costruttore non sembra avere nulla a che fare con ciò di cui stai parlando. Sono molto confuso. Qual è la tua raccolta di ciò che stai cercando di ordinare? –

+0

Hai perfettamente ragione, la prima linea funziona ma solo se utilizzo un tipo specifico derivato da ExtendedLookupManagerViewModel piuttosto che usare i generici. BrandName è una proprietà su MedicinalProductViewModel, ma se uso un altro tipo devo essere in grado di utilizzare un'altra proprietà. La domanda credo sia come posso usare un parametro passato invece di x.BrandName.Spero che lo renda un po 'più chiaro? – pilsdumps

risposta

2

Basta fare in modo che il simbolo del costruttore corrisponda al simbolo per il metodo di ordinamento e memorizzare nella cache i parametri da utilizzare nella raccolta quando viene chiamato Sort(). Quindi non "proprietà stringa", ma piuttosto qualunque sia il sig per il metodo di ordinamento.

Il parametro passato allora sarebbe un func che potrebbe essere di tipo specifico e indicazioni per l'elemento, l'istanza sarebbe

_medProd = new ExtendedLookupManagerViewModel<MedicinalProductViewModel, MedicinalProduct>(x => x.BrandName, ListSortDirection.Ascending); 
+0

Grazie gente, problema risolto, e col senno di poi sono un muppet. Ho aggiunto semplice Func sortby nel costruttore di ExtendedLookupManagerViewModel e l'ho chiamato come descritto da Jimmy sopra. La chiamata per ordinare ora è _lookuplistViewModel.Sort (_sortby, ListSortDirection.Ascending); Grazie ancora. – pilsdumps

1

Bene, il metodo Sort è solo generico in TKey - da dove viene T? Sospetto che dovrebbe essere Func<VMod, TKey> o Func<Mod, TKey> ma non sono sicuro di quale sia il risultato.

Che cosa sarebbe BrandName una proprietà di - MedicinalProductViewModel o MedicinalProduct? Supponendo che sia MedicinalProduct, il metodo deve essere dichiarato come:

public void Sort<TKey>(Func<Mod, TKey> keySelector, ListSortDirection direction) 

A quel punto ho il sospetto che funzionerà ...

+0

T è il tipo di SortableObservableCollection (public class SortableObservableCollection : ObservableCollection ). BrandName è una proprietà di entrambi, dal momento che VMod è un modello viewmodel che avvolge Mod (Modello). Il problema è che BrandName è una proprietà di un tipo specifico (ad esempio MedicinalProductViewModel), quindi devo utilizzare questo tipo di oggetto per eseguire il metodo di ordinamento. Voglio poter utilizzare qualsiasi tipo derivato da ExtendedLookupViewModel e specificare la proprietà da ordinare al posto di BrandName ma non so come sostituire x.BrandName con il mio parametro passato. – pilsdumps

+0

@pilsdumps: ma non stai chiamando Sort su 'SortableObservableCollection ' - lo stai chiamando su 'ExtendedLookupManagerViewModel '. Hai provato il cambiamento che ho suggerito? (Forse usando 'VMod' invece di' Mod'?) –

2

Non deve essere l'accettazione di un argomento proprietà stringa, ma piuttosto un Func<T, IComparable> dove T è probabilmente VMod o Mod, a seconda di cosa stai cercando di ordinare.

+0

Ok, l'avevo considerato, ma non sono sicuro di come lo avrei passato. Penso che TKey sia la chiave (proprietà) su T per ordinare, quindi come potrei fare per farlo? Somthing like _medProd = new ExtendedLookupManagerViewModel (Func pilsdumps

Problemi correlati