简体   繁体   English

在ObservableCollection上使用Lambda表达式

[英]Using Lambda Expression on an ObservableCollection

in my Silverlight 4 application, I have an ObservableCollection which consists of objects of a class and is defined by an interface: 在我的Silverlight 4应用程序中,我有一个ObservableCollection,它由一个类的对象组成,并由一个接口定义:

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

class myClass() : myInterface
{
  ...
}

ObservableCollection<myInterface> _collection;

Before adding a new element to the collection, I want to make sure, that the Name-Property does not already exists within the current collection elements. 在向集合添加新元素之前,我想确保Name-Property在当前集合元素中不存在。 As I cannot work with contains, I currently iterate through all elements and check each element manually. 由于我无法使用contains,我目前遍历所有元素并手动检查每个元素。

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

  return false;
}

I have read that this can also be achieved via a Lambda Expression, so I wrote the following: 我已经读过这也可以通过Lambda Expression实现,所以我写了以下内容:

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

But now I get an error, saying that the "lambda expression could not be converted to the Type "myInterface", because it is no delegate-type". 但是现在我收到一个错误,说“lambda表达式无法转换为Type”myInterface“,因为它不是委托类型”。 (Wording may differ, as I translated it from the german version) (措辞可能有所不同,因为我从德文版翻译了它)

I'm not sure what I have to change to make it work. 我不确定我需要改变什么才能让它发挥作用。 using System.Linq; is included. 已经包括了。 And the second question (or maybe the primary question): I have read, that the runtime changes from O(1) for the Contains()-method to O(n) - which isn't faster than my current check. 第二个问题(或者可能是主要问题):我已经读过,运行时从O(1)变为Contains() - 方法变为O(n) - 这不比我当前的检查快。 So does it even make sense to change it to using the lambda? 那么将它改为使用lambda甚至是否有意义? And finally, is there probably another method in checking for an existing Name-Property in my class? 最后,在我的班级中检查现有的Name-Property可能还有另一种方法吗?

Thanks in advance, 提前致谢,
Frank 坦率

  1. You don't have to write a Contains method, the Any method of Linq is already doing that: 您不必编写Contains方法,Linq的Any方法已经这样做了:

     if (!_collection.Any(p => p.Name == name2CheckAgainst)) 
  2. If you want to use a Lambda, you have to change the prototype of your Contains method to accept a Lambda (a lambda is just an alternative way to write an anonymous function): 如果要使用Lambda,则必须更改Contains方法的原型以接受Lambda(lambda只是编写匿名函数的另一种方法):

     private bool CollectionContainsElement(Func<myInterface, bool> lambda) { foreach (myInterface item in _collection) if (lambda(item)) return true; return false; } 
  3. Using a lambda here doesn't change the complexity of your function, it's O(n) in both case. 在这里使用lambda不会改变函数的复杂性,在这两种情况下都是O(n)。 So it's just a matter of preference. 所以这只是一个偏好问题。

You can use the Linq Any() method . 您可以使用Linq Any()方法 Which is useable like so: 哪个可用如下:

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

The reason why the contains method is O(1) is that under the covers it loads your collection into a HashTable (or similar) and uses the hash code (followed by a call to Equals) to check whether an element is present. contains方法是O(1)的原因是,它将您的集合加载到HashTable(或类似的)中并使用哈希代码(后跟对Equals的调用)来检查元素是否存在。

Contains is not a LINQ extension and therefore you can't use lambda expressions with it. Contains不是LINQ扩展,因此您不能使用lambda表达式。 It was designed to check if provided object exists in the list. 它旨在检查列表中是否存在提供的对象

As others have said, Any is a equivalent lambda-expression compatible extension method 正如其他人所说,Any是一种等效的lambda-expression兼容扩展方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM