【问题标题】:How to use IList.Contains() method to find an object如何使用 IList.Contains() 方法查找对象
【发布时间】:2012-03-26 09:45:57
【问题描述】:

我有一个公司类中的人员列表。

public class Company{
    IList<Person> persons;
}

然后我有一个公司列表,

IList<Company> companies;

现在我有了一个名字(比如“Lasantha”)。如果此名称是公司中任何人姓名的一部分,我想找到该公司。我尝试使用 company.Contains() 方法。我在 Person 类中重写了 object.Equals 方法,如下所示,

public override bool Equals(object o)
        {
            var other = o as Person;
            return this.Name.ToLower().Contains(other.Name.ToLower());
        }

但这不起作用。它也没有调用这个 Equal 方法。谁能帮帮我。

谢谢。

【问题讨论】:

    标签: c# .net .net-3.5


    【解决方案1】:

    以这种方式覆盖相等比较是错误的。

    平等应该是可传递的:如果

    "FooBar".Equals("Foo") == true
    

    那么它也必须持有那个

    "Foo".Equals("FooBar") == true
    

    但是,在这种情况下,您使用 Contains 会破坏传递性,因为“FooBar”包含“Foo”,但“Foo”不包含“FooBar”。除此之外,您不应该在一个类上覆盖 Equals 方法,除非该类的对象之间的每一个最后比较都具有相同的语义(在这种情况下,这似乎非常可疑)。

    那么,鉴于覆盖 Equals 不是解决方案,您应该怎么做

    一种方便的方法是使用 LINQ:

    var companiesWithPeopleWithLasanthaInTheirName = 
        companies.Where(c => c.persons.Any(p => p.Name.Contains("Lasantha")));
    

    但是上面的比较是区分大小写的,所以如果你不需要它,你必须调整它;这个问题有答案:Case insensitive 'Contains(string)'

    【讨论】:

    • 感谢您的描述性回答。
    【解决方案2】:

    你可以使用 Linq,比如

    var temp = companies.Where(p => p.People.Any(q => q.Name.Contains("Lasantha")));
    

    这是完整的例子;

    public class Example
    {
        private IList<Company> companies;
        public Example()
        {
            Person p1 = new Person(){Name = "Lasantha"};
            Person p2 = new Person(){Name = "Red Kid"};
            Company comp = new Company();
            comp.People = new List<Person>();
    
            comp.People.Add(p1);
            comp.People.Add(p2);
    
            companies = new List<Company>();
            companies.Add(comp);
    
            var temp = companies.Where(p => p.People.Any(q => q.Name.Contains("Lasantha")));
        }
    }
    
    public class Company
    {
        public IList<Person> People
        {
            get;
            set;
        }
    }
    
    public class Person
    {
        public string Name { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      您需要重载 Equals 以便将 Person 作为参数。否则默认为参考比较。

      public override bool Equals(Person p)
      {
         //...
      }
      

      那么正如msdn 所说,您可能还需要提供CompareTo (IComparable)。

      【讨论】:

        【解决方案4】:

        我认为你不需要重写 Equals 当你可以得到它时

        您应该使用 where 过滤公司,然后使用 Person 列表中的 Any 来获取符合您的姓名条件的公司

        companies.Where(c => c.persons.Any(p => p.Name.Contains("Value here"));
        

        【讨论】:

          【解决方案5】:

          你正在寻找

          1. 字符列表(“Lasantha”)
          2. 在人员列表中
          3. 在公司列表中

          嗯,其他贡献者已经描述了如何正确地做到这一点

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-07-29
            • 2018-12-17
            • 2015-01-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多