【问题标题】:Using Lambda Expression on an ObservableCollection在 ObservableCollection 上使用 Lambda 表达式
【发布时间】: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?

提前致谢,
弗兰克

【问题讨论】:

    标签: c# collections lambda contains


    【解决方案1】:
    1. 您不必编写 Contains 方法,Linq 的 Any 方法已经在这样做了:

      if (!_collection.Any(p => p.Name == name2CheckAgainst))
      
    2. 如果要使用 Lambda,则必须更改 Contains 方法的原型以接受 Lambda(lambda 只是编写匿名函数的另一种方法):

      private bool CollectionContainsElement(Func<myInterface, bool> lambda)
      {
        foreach (myInterface item in _collection)
          if (lambda(item))
            return true;
      
        return false;
      }
      
    3. 在这里使用 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)来检查元素是否存在.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多