在 ObservableCollection 上使用 Lambda 表达式

Posted

技术标签:

【中文标题】在 ObservableCollection 上使用 Lambda 表达式【英文标题】:Using Lambda Expression on an ObservableCollection 【发布时间】:2012-01-08 02:34:33 【问题描述】:

在我的 Silverlight 4 应用程序中,我有一个 ObservableCollection,它由一个类的对象组成并由一个接口定义:

interface myInterface()

  string Name  get; set; 
  string Value  get; set; 
 

class myClass() : myInterface

  ...


ObservableCollection<myInterface> _collection;

在向集合添加新元素之前,我想确保名称属性不存在于当前集合元素中。 由于无法使用包含,我目前遍历所有元素并手动检查每个元素。

private bool CollectionContainsElement(string name2CheckAgainst)

  foreach (myInterface item in _collection)
    if (item.Name.Equals(name2CheckAgainst))
      return true;

  return false;

我读到这也可以通过 Lambda 表达式来实现,所以我写了以下内容:

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

  ...

但是现在我收到一个错误,说“lambda 表达式无法转换为类型“myInterface”,因为它不是委托类型”。 (措辞可能不同,因为我是从德文翻译过来的)

我不确定我必须进行哪些更改才能使其正常工作。 using System.Linq; 包括在内。第二个问题(或者可能是主要问题):我已经读过,运行时从 Contains() 方法的 O(1) 更改为 O(n) - 这并不比我当前的检查快。那么将其更改为使用 lambda 是否有意义?最后,是否有另一种方法可以检查我的班级中现有的 Name-Property?

提前致谢, 弗兰克

【问题讨论】:

【参考方案1】:

    您不必编写 Contains 方法,Linq 的 Any 方法已经在这样做了:

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

    如果要使用 Lambda,则必须更改 Contains 方法的原型以接受 Lambda(lambda 只是编写匿名函数的另一种方法):

    private bool CollectionContainsElement(Func<myInterface, bool> lambda)
    
      foreach (myInterface item in _collection)
        if (lambda(item))
          return true;
    
      return false;
    
    

    在这里使用 lambda 不会改变函数的复杂性,在这两种情况下都是 O(n)。所以这只是一个偏好问题。

【讨论】:

非常感谢,看来我误读了包含方法中 lamda 的示例。使用 Any 很明显 :)【参考方案2】:

Contains 不是 LINQ 扩展,因此您不能对它使用 lambda 表达式。它旨在检查提供的 object 是否存在于列表中。

正如其他人所说,Any 是等效的 lambda 表达式兼容扩展方法

【讨论】:

【参考方案3】:

您可以使用Linq Any() method。可以这样使用:

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


contains 方法为 O(1) 的原因在于,它在幕后将您的集合加载到 HashTable(或类似的)中,并使用哈希码(随后调用 Equals)来检查元素是否存在.

【讨论】:

以上是关于在 ObservableCollection 上使用 Lambda 表达式的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 上使图像透明?

如何在 Swift 上使这段代码异步

如何在 Blazorise 上使验证日期不为空

WPF ObservableCollection 异步调用问题

为啥在 DataGrid 中刷新 ObservableCollection 很慢

如何在移动视图上使输入和按钮堆栈相互叠加