2011-11-28 29 views
5

en mi aplicación de Silverlight 4, tengo una ObservableCollection que consiste en objetos de una clase y se define por una interfaz:Usando expresión lambda en una ObservableCollection

interface myInterface() 
{ 
    string Name { get; set; } 
    string Value { get; set; } 
} 

class myClass() : myInterface 
{ 
    ... 
} 

ObservableCollection<myInterface> _collection; 

Antes de añadir un nuevo elemento a la colección, me quiero asegurarme de que Name-Property no exista ya dentro de los elementos de la colección actual. Como no puedo trabajar con contiene, actualmente recorro todos los elementos y verifico cada elemento manualmente.

private bool CollectionContainsElement(string name2CheckAgainst) 
{ 
    foreach (myInterface item in _collection) 
    if (item.Name.Equals(name2CheckAgainst)) 
     return true; 

    return false; 
} 

He leído que esto también se puede lograr a través de una expresión lambda, por lo que escribió lo siguiente:

if (!_collection.Contains(p => p.Name == name2CheckAgainst)) 
{ 
    ... 

Pero ahora me sale un error, diciendo que la "expresión lambda no puede ser convertido al tipo "myInterface", porque no es de tipo delegado ". (La redacción puede diferir, ya que la traduje de la versión alemana)

No estoy seguro de qué tengo que cambiar para que funcione. using System.Linq; está incluido. Y la segunda pregunta (o tal vez la pregunta principal): He leído que el tiempo de ejecución cambia de O (1) para el método Contiene() a O (n), que no es más rápido que mi verificación actual. Entonces, ¿tiene sentido cambiarlo a usar el lambda? Y, por último, ¿hay probablemente otro método para verificar una Nombre-Propiedad existente en mi clase?

Gracias de antemano,
Frank

Respuesta

15
  1. Usted no tiene que escribir una Contiene método, el método de LINQ Cualquier ya está haciendo que:

    if (!_collection.Any(p => p.Name == name2CheckAgainst)) 
    
  2. Si desea utilizar una Lambda, usted tiene que cambiar el prototipo de su método Contains a aceptar una lambda (lambda es sólo una forma alternativa de escribir una función anónima):

    private bool CollectionContainsElement(Func<myInterface, bool> lambda) 
    { 
        foreach (myInterface item in _collection) 
        if (lambda(item)) 
         return true; 
    
        return false; 
    } 
    
  3. el uso de un lambda aquí no cambia la complejidad de su functi encendido, es O (n) en ambos casos. Entonces es solo una cuestión de preferencia.

+0

muchas gracias, parece que he leído mal el ejemplo withe la lambda contiene en el método. Usar Any es obvio :) – Aaginor

2

Usted puede utilizar el Linq Any() method. ¿Qué es utilizable como tal:

if (!_collection.Any(p => p.Name == name2CheckAgainst)) 
{ 
} 

La razón por la cual el método contains es O (1) es que bajo las sábanas se carga su colección en una tabla hash (o similar) y utiliza el código hash (seguida de una llamada Igual a) para verificar si un elemento está presente.

1

Contiene no es una extensión LINQ y por lo tanto no puede usar expresiones lambda con ella. Fue diseñado para verificar si el objeto existe en la lista.

Como han dicho otros, es un equivalente Cualquier lambda-expresión método de extensión compatibles

Cuestiones relacionadas