【问题标题】:C# List<myClass> ContainsC# List<myClass> 包含
【发布时间】:2020-06-16 02:45:57
【问题描述】:

好的,所以我有一个我自己的类类型的列表,它又具有字符串和整数等参数,如果我与用户输入的内容匹配,我想使用 Contains() 检查我的列表.

至于示例,您可以假设列表中已经有成员。

class Person 
{
    public string Name {get; set;}
    public int Age {get; set;}
    public int Id {get; set;}

    public Person()
    {
    }
}

class PersonList : Person
{
    List<Person> personList = new List<Person>();

    public bool Exist(int inputParameter)
    {
       if (personList.Contains(new Person { Id = inputParameter }))
       {
           return true;
       }
       else
       {
           return false;
       }
    }
}

现在,即使我确定输入属于列表中已经存在的成员,我的 Exist 方法也总是返回 false。有没有人知道我做错了什么?

【问题讨论】:

  • personList.Any(person =&gt; person.Id == inputParameter);
  • 这确实严格引用等于 - 像 c 的指针一样思考。
  • 这能回答你的问题吗? LINQ: "contains" and a Lambda query

标签: c# .net class


【解决方案1】:

你也可以用Any代替Contains,试试把Exist方法的代码改成:

public bool Exist(int inputParameter)
{
    return personList.Any(person => person.Id == inputParameter);
}

【讨论】:

    【解决方案2】:

    .Contains() 方法uses the default equality comparer,这意味着它为类型调用.Equals() 方法来查找匹配项。

    对于像Person 类这样的引用类型,从Object 继承的默认方法使用引用相等,这意味着它只会返回true,如果它们是完全相同的对象实例。如果你想要不同类型的比较,你应该在类型中重载 Equals() 方法(并在你使用它时实现 IEquatable&lt;T&gt; 并覆盖 GetHashCode())。

    public class Person : IEquatable<Person>
    {
        public string Name {get; set;}
        public int Age {get; set;}
        public int Id {get; set;}
    
        public bool Equals(Person other)
        {
            return other is Object && this.Id == other.Id;
        }
    
        public override bool Equals(Object other)
        {
            if (other is Person) return Equals((Person)other);
            return false;
        }
    
        public override int GetHashCode()
        {   //naive implementation. This is adequate as long as you're **SURE** all instances will have a unique/correct `Id` value.
            return this.Id.GetHashCode();
        }
    }
    

    除此之外,我不会建立一个单独的PersonList 类型List&lt;Person&gt; 泛型集合几乎可以肯定已经满足了您的需求。

    顺便说一句,仍然值得讨论如何从原始 PersonList 类中实现 Exist() 方法。我在这里要做的一件事是避免尝试分配新对象来完成搜索。考虑到这一点:

    public bool Exist(int inputParameter)
    {
        return personList.Any(p => p.Id == inputParameter);
    }
    

    请注意,在大多数情况下,这目前仍会分配一个新的迭代器对象,但随着时间的推移,正在努力使这些 linq 操作对内存更加友好。它的代码也少了很多。如果您有一个函数可以为您提供boolean 结果,那么没有充分的理由将它放在if() 块中只是为了返回相同的结果。

    如果我们想在分配上变得非常积极,我们可以这样做:

    public bool Exist(int inputParameter)
    {
        foreach(var p in personList)
        {
           if (p.Id == inputParameter) return true;
        }
        return false;
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用Any

       public bool Exist(inputParameter)
          {
             if (personList.Any(person => person.Id == inputParameter))
             {
                 return true;
             }
             else
             {
                 return false;
             }
          }
      

      你可以折叠成这样:

      public bool Exist(inputParameter)
      {
        return personList.Any(person => person.Id == inputParameter);
      }
      

      【讨论】:

      • @Antnrmnd - 我已将其改为使用 Any
      • Any 返回一个布尔值。为什么要这么冗长?
      猜你喜欢
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2013-09-21
      • 2015-05-22
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      相关资源
      最近更新 更多