C# Список <myClass>Содержит - PullRequest
0 голосов
/ 03 марта 2020

Хорошо, у меня есть список типа моего собственного класса, который, в свою очередь, имеет параметры, такие как строки и целые числа, и я хочу проверить в моем списке с помощью 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. Кто-нибудь знает, что я не правильно делаю?

Ответы [ 3 ]

3 голосов
/ 03 марта 2020

Вы также можете использовать Any вместо Contains, попробуйте изменить код метода Exist на:

public bool Exist(int inputParameter)
{
    return personList.Any(person => person.Id == inputParameter);
}
2 голосов
/ 03 марта 2020

Метод .Contains() использует средство сравнения по умолчанию , что означает, что он вызывает метод .Equals() для типа, чтобы найти совпадение.

Для ссылочных типов, таких как ваш класс Person, метод по умолчанию, унаследованный от Object, использует равенство ссылок , то есть он вернет true, только если они точны тот же экземпляр объекта . Если вам нужен другой тип сравнения, вам следует перегрузить метод Equals() в этом типе (и реализовать IEquatable<T> и переопределить 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<Person> generi c почти наверняка уже делает то, что вам нужно.

В любом случае, все еще стоит рассмотреть, как можно реализовать метод Exist() из оригинального PersonList учебный класс. Одна вещь, которую я хотел бы сделать здесь, - это избегать попыток выделить новые объекты для завершения поиска. Имея это в виду:

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;
}
1 голос
/ 03 марта 2020

Вы можете использовать Любой

 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);
}
...