【问题标题】:LINQ Project properties into a new anonymous type with ContainsLINQ 项目属性转换为包含包含的新匿名类型
【发布时间】:2015-03-07 18:40:21
【问题描述】:

我有以下代码,我正在尝试使其工作,但它仍然无法编译。谢谢。

List<Employee> emploees = new List<Employee>() 
{ 
    new Employee { ID = 101, Name = "Rosy" },
    new Employee { ID = 102, Name = "Sury" }
};

var result = emploees.Select(x=> new {x.ID, x.Name}).Contains(new Employee { ID = 101, Name = "Rosy" });
        Console.WriteLine(result);

【问题讨论】:

  • 我只是想知道,为什么你需要创建匿名类型,如果你只需要检查员工是否存在于数组中??

标签: c# linq linq-to-objects anonymous-types


【解决方案1】:

首先,您不需要将列表项投影到匿名对象。 此外,IMO Any()Contains() 更适合这种情况:

var result = emploees.Any(x => x.ID == 101 && x.Name == "Rosy");

如果您仍想使用Contains,则需要为Employee 类创建比较器

sealed class MyComparer : IEqualityComparer<Employee>
{
    public bool Equals(Employee x, Employee y)
    {
        if (x == null)
            return y == null;
        else if (y == null)
            return false;
        else
            return x.ID == y.ID && x.Name == y.Name;
    }

    public int GetHashCode(Employee obj)
    {
         unchecked
         {
              int hash = 17;
              hash = hash * 23 + obj.ID.GetHashCode();
              hash = hash * 23 + obj.Name.GetHashCode();
              return hash;
        }
    }
}

并将您的代码更改为:

  var result = emploees.Contains(new Employee { ID = 101, Name = "Rosy" }, new MyComparer());

【讨论】:

  • 感谢您的回答。但是如果我想保持包含呢?
  • @NicolaSmith 然后你需要创建你的比较器,
  • @NicolaSmith 很高兴为您提供帮助,我已经按照您的意愿更新了我的答案。
【解决方案2】:

为什么要投影到匿名类型然后进行类型比较检查?

您可以在这里简单地使用Any 来实现您所需要的:

var result = emploees
   .Select(x=> new {x.ID, x.Name})
   .Any(x => x.ID == 101 && x.Name == "Rosy");
    Console.WriteLine(result);

或者简单地说,没有Select,因为您只是使用bool

bool result = emploees
   .Any(x => x.ID == 101 && x.Name == "Rosy");
    Console.WriteLine(result);

为了完整起见,如果您真的想使用 Contains,请为您的 Employee 类覆盖 IEquatable

public class Employee : IEquatable<Employee>
{
    public bool Equals( Employee other)
    {
        return this.ID == other.ID && 
           this.Name == other.Name;
    }
}

然后做:

var result = emploees
    .Select(x => new Employee {x.ID, x.Name})
    .Contains(new Employee { ID = 101, Name = "Rosy" });

    Console.WriteLine(result);

【讨论】:

  • 使用第三种方法,您必须检查 Contains 与集合中 Employee 的相同引用,或者让 Employee 类覆盖相等比较以比较给定字段。
  • @YoryeNathan 是的,你是对的。因为 Contains 的价值是太多的额外工作,所以我删除了那个例子,当 Any 可以在这里完美地完成工作时,重写相等比较器是没有意义的。
  • 谢谢你 mattytommo。
  • @NIcolaSmith 没问题,我实际上添加了一个变体来使用Contains,仅供参考。
猜你喜欢
  • 1970-01-01
  • 2013-03-25
  • 2016-06-22
  • 1970-01-01
  • 2019-06-25
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多