2015-10-18 8 views
1

У меня есть класс Person с именем. У меня есть коллекция людей. У меня есть способ добавить нового человека, но мне нужно проверить, что коллекция уже содержит человека.Inline Comparer

Я хотел бы использовать coll.Contains(newPerson,[here is the comparer]), где сопоставитель сравним свойства имени. Можно ли сделать сравнение inline (анонимно) без создания нового класса, реализующего IEqualityComparer?

+0

Какие действия вы выполняете по данной коллекции? –

ответ

1

В случае, если вы не хотите дублировать Person объекты, и хотите работать на этой коллекции в виде набора, вы можете использовать вместо HashSet<Person>, который при вызове его метода Add будет делать чек, если такой человек уже существует. Для этого вы можете реализовать IEquatable<Person> в своем классе. Это будет выглядеть примерно так:

public class Person : IEquatable<Person> 
{ 
    public Person(string name) 
    { 
     Name = name; 
    } 

    public string Name { get; private set; } 

    public bool Equals(Person other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != this.GetType()) return false; 
     return Equals((Person) obj); 
    } 

    public override int GetHashCode() 
    { 
     return (Name != null ? Name.GetHashCode() : 0); 
    } 

    public static bool operator ==(Person left, Person right) 
    { 
     return Equals(left, right); 
    } 

    public static bool operator !=(Person left, Person right) 
    { 
     return !Equals(left, right); 
    } 
} 

И теперь вы можете использовать его в HashSet<Person> как этот:

void Main() 
{ 
    var firstPerson = new Person { Name = "Yuval" }; 
    var secondPerson = new Person { Name = "yuval" }; 
    var personSet = new HashSet<Person> { firstPerson }; 
    Console.WriteLine(personSet.Add(secondPerson)); // Will print false. 
} 

Примечание это не даст вам гибкость нескольких компараторов, но таким образом вы не нужно будет создавать новый класс, реализующий IEqualityComparer<T>.

1

Вместо этого вы можете использовать linq.

bool contains = coll.Any(p => p.Name == newPerson.Name); 

Здесь вы можете добавить все условия, как вы захотите. например, поскольку WaiHaLee отметил, что вы можете сделать случай сравнения с игнорированием.

bool contains = coll.Any(p => p.Name.Equals(newPerson.Name, StringComparison.OrdinalIgnoreCase)); 
+0

Я предлагаю вам сопоставить имя с использованием инвариантной культуры и игнорировать случай, чтобы «john smith» сравнивался с «JOHN SMITH» и обрабатывал [Turkish I] (https://msdn.microsoft.com/en- нас/библиотека/ms994325.aspx # cltsafcode_topic4). –

Смежные вопросы