2010-07-27 21 views
7

Por lo tanto, estoy un poco fuera de mi zona de confort cuando trato con Func <>, genéricos y expresiones lambda, pero creo que tengo la idea general (algo así) pero todavía un poco confundido.C# Func <> y genéricos

He implementado la clase SortableObservableCollection (tomado de algún lugar en línea - gracias a quienquiera que fuese Me lo dio!) Y se utiliza como esto:

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

donde x es el tipo de objeto implementado por la colección sortable En este caso, BrandName es una propiedad del tipo de objeto implementado, pero quiero usar el código anterior en una clase genérica y pasar la propiedad en la que desea ordenar. El método Sort se ve así:

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 clase genérica en la que se define el método de ordenación que se llama así:

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

y me gustaría crear una instancia de esta manera:

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

donde property es la propiedad en el que se ordenan. Idealmente, esto debería ser seguro, pero una cadena será suficiente.

Puede alguien ayudarme a dirigirlo en la dirección correcta, por favor?

+3

estoy bastante bien con lambdas y los genéricos, pero no puedo averiguar qué usted está pidiendo, la primera línea de código que publicó hace lo que está pidiendo a partir de su descripción de los requisitos, pero su sig de constructor parece no tener nada que ver con lo que está hablando. Estoy muy confundido. ¿De qué colección está tratando de ordenar? –

+0

Tiene razón, la primera línea funciona, pero solo si uso un tipo específico derivado de ExtendedLookupManagerViewModel en lugar de usar genéricos. BrandName es una propiedad de MedicinalProductViewModel, pero si utilizo otro tipo, debo poder usar otra propiedad. La pregunta que supongo es cómo puedo usar un parámetro pasado en lugar de x.BrandName.Espero que eso lo aclare un poco? – pilsdumps

Respuesta

2

Simplemente haga que su constructor sig coincida con sig para el método de clasificación, y guarde en caché los parámetros para usar en la colección cuando se llame a Sort(). Por lo tanto, no es "propiedad de cadena", sino más bien lo que sea que sig sea para el método de clasificación.

El parámetro que se pasa entonces sería una func que podrían ser de tipo específico y que le dirige al elemento, la creación de instancias sería

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

Gracias amigos, problema resuelto, y en retrospectiva, soy un muppet. Simplemente agregué Func sortby en el constructor de ExtendedLookupManagerViewModel, y lo llamé como lo describe Jimmy arriba. La llamada para ordenar ahora es _lookuplistViewModel.Sort (_sortby, ListSortDirection.Ascending); Gracias de nuevo. – pilsdumps

1

Bueno, su método de ordenación solo es genérico en TKey - ¿De dónde viene T? Sospecho que debería ser Func<VMod, TKey> o Func<Mod, TKey>, pero no estoy seguro de lo que has mostrado.

¿Cuál sería BrandName ser una propiedad de - MedicinalProductViewModel o MedicinalProduct? Asumiendo que es MedicinalProduct, el método debe ser declarado como:

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

En ese momento me sospecho que va a funcionar ...

+0

T es el tipo de SortableObservableCollection (clase pública SortableObservableCollection : ObservableCollection ). BrandName es una propiedad de ambos ya que VMod es un modelo de envoltura Mod (Model). El problema es que BrandName es una propiedad de un tipo específico (es decir, MedicinalProductViewModel), así que tengo que usar este tipo de objeto para ejecutar el método de clasificación. Quiero poder utilizar cualquier tipo derivado de ExtendedLookupViewModel y especificar la propiedad para ordenar en lugar de BrandName, pero no sé cómo reemplazar x.BrandName con mi parámetro pasado. – pilsdumps

+0

@pilsdumps: pero no está llamando a Sort en 'SortableObservableCollection ' - lo está llamando en 'ExtendedLookupManagerViewModel '. ¿Has probado el cambio que sugerí? (¿Posiblemente usando 'VMod' en lugar de' Mod'?) –

2

No deberías estar aceptando un argumento propiedad de cadena, sino más bien un Func<T, IComparable> donde T es probablemente VMod o Mod, dependiendo de lo que intente ordenar.

+0

Ok, lo había considerado pero no estoy seguro de cómo pasaría eso. Creo que TKey es la clave (propiedad) en T para ordenar, por lo que ¿cómo podría hacerlo? Algo así como _medProd = new ExtendedLookupManagerViewModel (Func pilsdumps

Cuestiones relacionadas