2010-07-27 14 views
7

Więc, jestem trochę poza moją strefą komfortu, kiedy mam do czynienia z Func <>, Generics i wyrażeniami lambda, ale myślę, że dostaję ogólny pomysł (rodzaj), ale wciąż trochę zdezorientowany.C# Func <> i generics

I zostały wdrożone klasę SortableObservableCollection (wzięte z gdzieś w Internecie - dzięki temu, kto to był Dostałem go od!) I jest on stosowany tak:

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

gdzie x jest typ obiektu realizowane przez sortowalna kolekcja. W tym przypadku BrandName jest właściwością typu obiektu zaimplementowanego, ale chcę użyć powyższego kodu w klasie ogólnej i przekazać właściwość do sortowania. Sortuj metoda wygląda następująco:

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

Klasa rodzajowe, w którym metoda sortowania jest nazywane jest zdefiniowany następująco:

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

i chciałabym utworzyć instancję o tym tak:

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

gdzie property jest właściwością do posortowania. Najlepiej byłoby, gdyby był bezpieczny, ale wystarczy napis.

Czy ktoś może pomóc w skierowaniu mnie we właściwym kierunku, proszę?

+3

jestem całkiem w porządku z lambdas i rodzajowych, ale nie mogę dowiedzieć się, co o co prosisz, pierwsza linia opublikowanego kodu robi to, o co prosisz, z opisu wymagań, ale twój konstruktor sig nie ma nic wspólnego z tym, o czym mówisz. Jestem zdezorientowany. Jaka jest Twoja kolekcja tego, co próbujesz sortować? –

+0

Masz całkowitą rację, pierwsza linia działa, ale tylko wtedy, gdy korzystam z określonego typu pochodzącego z narzędzia ExtendedLookupManagerViewModel, zamiast używać generycznych. BrandName jest właściwością produktu MedicinalProductViewModel, ale jeśli używam innego typu, muszę mieć możliwość korzystania z innej właściwości. Pytanie, jak sądzę, w jaki sposób mogę użyć przekazanego parametru zamiast x.BrandName.Mam nadzieję, że czyni to nieco jaśniejszym? – pilsdumps

Odpowiedz

2

Wystarczy, że twój konstruktor sig dopasuje sig do metody sortowania i zapisze w pamięci podręcznej paramy do użycia w kolekcji, gdy zostanie wywołana funkcja Sort(). Więc nie "właściwość string", ale raczej cokolwiek sig jest dla metody sortowania.

przekazany parametr wtedy byłby func, które mogą być typu specyficzne i kierowanie do elementu, konkretyzacja byłoby

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

Dzięki ludziom, problem rozwiązany, a po fakcie jestem muppet. Po prostu dodałem Func sortby w konstruktorze narzędzia ExtendedLookupManagerViewModel i wywołałem go w sposób opisany powyżej przez Jimmy'ego. Wywołanie sortowania to _lookuplistViewModel.Sort (_sortby, ListSortDirection.Ascending); Jeszcze raz dziękuję. – pilsdumps

1

Cóż, twoja metoda sortowania jest tylko ogólna w TKey - skąd pochodzi T? Podejrzewam, że powinien to być albo Func<VMod, TKey> lub Func<Mod, TKey>, ale nie jestem pewien, co wynika z tego, co pokazałeś.

Co by BrandName było własnością - MedicinalProductViewModel lub MedicinalProduct? Zakładając, że to MedicinalProduct, metoda powinna być uznana jako:

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

W tym momencie Podejrzewam to działa ...

+0

T jest typem SortableObservableCollection (klasa publiczna SortableObservableCollection : ObservableCollection ). BrandName jest właściwością obu, ponieważ VMod jest modem opakowującym viewmodel (Model). Problem polega na tym, że BrandName jest właściwością określonego typu (np. MedicinalProductViewModel), więc muszę użyć tego typu obiektu, aby uruchomić metodę sortowania. Chcę móc używać dowolnego typu pochodzącego z ExtendedLookupViewModel i określić właściwość do sortowania zamiast BrandName, ale nie wiem, jak zastąpić x.BrandName moim przekazanym parametrem. – pilsdumps

+0

@pilsdumps: Ale nie wywołujesz sortowania na 'SortableObservableCollection ' - wywołujesz to na 'ExtendedLookupManagerViewModel '. Czy próbowałeś zmiany, którą zasugerowałem? (Prawdopodobnie używając 'VMod' zamiast' Mod'?) –

2

Nie powinno być przyjęcie właściwości String argumentu, lecz Func<T, IComparable> gdzie T jest prawdopodobnie VMod lub Mod, w zależności od tego, co próbujesz posortować.

+0

OK, rozważałem to, ale nie jestem pewna, jak to zrobić. Myślę, że TKey jest kluczem (właściwością) na T, aby sortować, więc jak miałbym to zrobić? Coś takiego jak _medProd = new ExtendedLookupManagerViewModel (Func pilsdumps

Powiązane problemy