2010-07-27 20 views
7

Also, ich bin ein wenig außerhalb meiner Komfortzone, wenn ich mit Func <>, Generics und Lambda Ausdrücke, aber ich denke, ich bekomme die allgemeine Idee (Art), aber immer noch ein bisschen verwirrt.C# Func <> und Generika

ich die SortableObservableCollection Klasse implementiert haben (von irgendwo online genommen - dank wer auch immer es war habe ich es aus!) Und es wie folgt verwendet:

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

wobei x der Objekttyp von implementiert wird die sortierbare Sammlung. In diesem Fall ist BrandName eine Eigenschaft des Typs des implementierten Objekts, aber ich möchte den obigen Code in einer generischen Klasse verwenden und die zu sortierende Eigenschaft übergeben. Die Sort-Methode sieht wie folgt aus:

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

Die generische Klasse, auf dem die Sort-Methode ist wie folgt definiert genannt:

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

und ich möchte eine Instanz davon wie diese erstellen:

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

wo property ist das Grundstück, auf dem sortieren. Idealerweise sollte dies typsicher sein, aber eine Zeichenfolge reicht aus.

Kann mir bitte jemand helfen, mich in die richtige Richtung zu lenken?

+3

Ich bin ziemlich in Ordnung sein, aber ich kann nicht herausfinden, was Du fragst nach, die erste Codezeile, die du gepostet hast, erfüllt das, was du von deiner Beschreibung der Anforderungen verlangst, aber dein Konstruktor scheint nichts mit dem zu tun zu haben, worüber du sprichst. Ich bin sehr verwirrt. Was ist Ihre Sammlung, die Sie sortieren möchten? –

+0

Sie sind genau richtig, die erste Zeile funktioniert aber nur, wenn ich einen bestimmten Typ verwende, der von ExtendedLookupManagerViewModel abgeleitet ist, anstatt Generics zu verwenden. BrandName ist eine Eigenschaft von MedicinalProductViewModel, aber wenn ich einen anderen Typ verwende, muss ich eine andere Eigenschaft verwenden können. Die Frage ist, wie kann ich einen übergebenen Parameter anstelle von x.BrandName verwenden.Hoffe das macht es ein bisschen klarer? – pilsdumps

Antwort

2

Stellen Sie einfach Ihr Konstruktorsig mit dem Sig für die sort-Methode und zwischenspeichern Sie die Parameter für die Verwendung in der Sammlung, wenn Sort() aufgerufen wird. Also nicht "String-Eigenschaft", sondern was auch immer die Sig für die Sortiermethode ist.

Der übergebene Parameter dann wäre eine func, die typspezifischen und Richten Sie auf das Element sein könnte, wäre die Instanziierung mit Lambdas und Generika

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

Danke Leute, Problem gelöst, und im Nachhinein bin ich ein Muppet. Ich füge einfach Func sortby in den Konstruktor von ExtendedLookupManagerViewModel, und nannte es wie von Jimmy oben beschrieben. Der Aufruf zum Sortieren ist jetzt _lookuplistViewModel.Sort (_sortby, ListSortDirection.Ascending); Danke nochmal. – pilsdumps

1

Nun, Ihre Sort-Methode ist nur generisch in TKey - woher kommt T? Ich vermute, es sollte entweder Func<VMod, TKey> oder Func<Mod, TKey> sein, aber ich bin unsicher, was von dem, was Sie gezeigt haben.

Was wäre BrandName eine Eigenschaft von - MedicinalProductViewModel oder MedicinalProduct? Unter der Annahme, es ist MedicinalProduct, sollte Ihre Methode deklariert werden:

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

An diesem Punkt ich vermute, dass es funktionieren wird ...

+0

T ist der Typ von SortableObservableCollection (öffentliche Klasse SortableObservableCollection : ObservableCollection ). BrandName ist eine Eigenschaft von beiden, da VMod ein Viewmodel-Wrapping-Mod (Model) ist. Das Problem ist, dass BrandName eine Eigenschaft eines bestimmten Typs ist (z. B. MedicinalProductViewModel), also muss ich diesen Objekttyp verwenden, um die Sortiermethode auszuführen. Ich möchte in der Lage sein, jeden Typ zu verwenden, der von ExtendedLookupViewModel abgeleitet wird, und die Eigenschaft anzugeben, nach der anstelle von BrandName sortiert werden soll, aber ich weiß nicht, wie ich x.BrandName durch meinen übergebenen Parameter ersetzen kann. – pilsdumps

+0

@pilsdumps: Aber Sie rufen nicht Sortieren auf der 'SortableObservableCollection ' - Sie rufen es auf 'ExtendedLookupManagerViewModel '. Hast du die Änderung versucht, die ich vorgeschlagen habe? (Vielleicht mit 'VMod' anstelle von' Mod'?) –

2

Sie sollten ein String-Eigenschaft Argument nicht akzeptieren werden, sondern ein Func<T, IComparable> wo T ist wahrscheinlich entweder VMod oder Mod, abhängig davon, was Sie sortieren möchten.

+0

Ok, ich habe das bedacht, aber ich bin mir nicht sicher, wie ich das weitergeben würde. Ich denke, TKey ist der Schlüssel (Eigenschaft) auf T, um zu sortieren, also Wie würde ich es tun? Etwas wie _medProd = new ExtendedLookupManagerViewModel (Func pilsdumps

Verwandte Themen