Несколько подходов, с разными плюсами и минусами:
list.Any(item => item.ID == newItem.ID)
возвращает true, если есть совпадающий идентификатор, хотя это то же самое, что и цикл (и действительно немного дороже из-за лямбды), но чищеcode.
Поддержание HashSet, в котором компаратор сравнивает свойство ID, будет означать, что новые значения с существующим идентификатором не будут добавлены.
Сохранение списка в порядке идентификаторов позволит вам быстролибо найдите существующий объект в O (log n) сложности времени, используя BinarySearch()
, либо найдите место, куда вы должны вставить этот новый элемент для поддержания порядка.
Если ID действительно идентифицирует объекты (то естьскажем, когда идентификаторы равны, объекты следует считать равными), затем реализуем IEquatable<T>
для сравнения на основе идентификатора, переопределяем object.Equals()
для вызова в этот метод равенства для конкретного типа и переопределяем GetHashCode()
для возврата значенияID (если это int
, или меньший целочисленный тип, или приведение к int
, если это uint
) или хэш-код ID (если это 'Это другой тип) будет означать, что это становится концепцией идентичности по умолчанию, то есть HashSet не будет нуждаться в специальном компараторе, и Contains
сделает всю работу за вас (обратите внимание, что Contains
, по сути, тоже цикл).