[英]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 坦率
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))
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; }
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.