【问题标题】:Check property of List if it is of a given type检查 List 的属性是否属于给定类型
【发布时间】:2015-02-19 08:48:08
【问题描述】:

我有这个类结构

public class A
{
    int number;
}

public class B : A
{
    int otherNumber;
}

我想在A 的列表中搜索项目,其中number 大于给定值并且otherNumber 大于另一个给定值(如果它们的类型为B)。我正在寻找类似的东西:

var results = list.Where(x => x.number>5 && x.otherNumber>7).ToList();

其中listList<A>

我目前的做法是:

var results = list.Where(x => x.number>5);
foreach(var result in results)
{
    B b = result As B;
    if(b!=null && b.otherNumber>7)
        [...]
}

【问题讨论】:

  • 你可以编写一个自定义比较器,或者一个可覆盖的比较函数,5 和 7 显然不是硬编码在实际代码中的,对吧?如果您提供了问题的描述,而不是您尝试解决未知问题的问题,我们可能会更有帮助。
  • 你是对的,数字不是硬编码的。事实上,它们甚至不是整数。我试图把问题写得尽可能简单易行。我认为提供的答案是一个很好的方法,正是我所需要的。更多详细信息:我尝试在列表中找到具有最佳属性的A。一些As 有更多的信息,可以考虑,但我不确定我能做到这一点。

标签: c# linq list search inheritance


【解决方案1】:

这里 - 只有 B 对象将是匹配条件,所以最简短的形式是:

list.OfType<B>().Where(x=>x.num1 > 5 && x.num2 < 7);

【讨论】:

  • 这不会只为我提供B 类型的对象,而不是A
【解决方案2】:

您可以按number 字段过滤(假设字段是公开的)。如果 a 是 B 类型,则按 otherNumber 字段过滤。否则第二次过滤将跳过

list.Where(a => a.number > 5).Where(a => !(a is B) || ((B)a).otherNumber > 7)

也许更易读的方式:

list.Where(a => {
   var b = a as B;
   return a.number > 5 && (b == null || b.otherNumber > 7);
})

或查询语法

from a in list
let b = a as B
where a.number > 5 && (b == null || b.otherNumber > 7)

【讨论】:

  • !(a is B) 是与|| 结合使用的明智之举。我喜欢。您认为前两种方法在性能上有区别吗?
  • @jasdefer:以上代码性能不是问题,可读性是。
  • @jasdefer EF 是另一回事。 EF用的是Expression而不是Func,这个表达式应该可以转换成SQL代码。正如错误告诉你的那样,SQL 语言中没有类型转换的等价物。使用 EF,您可以使用 entities.Where(a =&gt; a.number &gt; 5).Except(entities.OfType&lt;B&gt;().Where(b =&gt; b.otherNumber &lt;= 7))
  • @jasdefer 您可以在服务器端按数字进行过滤,然后将任何其他过滤移至客户端。例如。 entities.Where(a =&gt; a.number &gt; 5).AsEnumerable().Where(...)
  • entities.Where(a =&gt; a.number &gt; 5).AsEnumerable().Where(a =&gt; !(a is B) || ((B)a).otherNumber &gt; 7) 工作正常 :) 谢谢你的帮助!
【解决方案3】:

选择所有不大于 7 的Bs:

var badBs = list.OfType<B>().Where(x => x.otherNumber <= 7);

选择所有符合第一个要求的项目,除了那些不符合第二个要求的项目:

var results = list.Where(x => x.number > 5).Except(badBs);

【讨论】:

  • 这比我的方法好,谢谢你的回答。但我认为另一个答案更好。
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2011-03-21
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
相关资源
最近更新 更多