2015-08-13 4 views
3

У меня есть список объектов класса и хочу удалить один элемент, но это не распространяется работа:Удалить элемент из списка по значению

class Person 
    { 
     public string name; 
     public Person(string s) 
     { 
      this.name = s; 
     } 
    } 

    void ABC() 
    { 
     List<Person> newPersonList = new List<Person>(); 
     newPersonList.Add(new Person("A")); 
     newPersonList.Add(new Person("B")); 
     newPersonList.Add(new Person("C")); 

     newPersonList.Remove(A); 
     newPersonList.RemoveAt(1); 
    } 

RemoveAt (1) работает и удаляет элемент с ID 1.

Я думаю, что Remove (A) должен удалить элемент со значением «A». Но это не работает. Может кто-нибудь объяснить, почему? И какой правильный способ удалить по значению?

+1

Как вы думаете, что должно произойти в 'Remove (A);'? Вы не объявили 'A'. В общем случае вам нужно переопределить 'Equals' в' Person' или/и реализовать 'IEquatable ' –

ответ

6

Самый простой способ, чтобы удалить из списка по значению свойства элемента:

newPersonList.RemoveAll(p => p.name == "A"); 

Nicer способом было бы изменить Person вроде:

class Person : IEquatable<Person> 
{ 
    public readonly string Name; 
    public Person(string name) 
    { 
     if (string.IsNullOrWhiteSpace(name)) 
      throw new ArgumentException("name"); 
     Name = name; 
    } 
    public static implicit operator string(Person p) 
    { 
     return p.Name; 
    } 
    public static implicit operator Person(string name) 
    { 
     return new Person(name); 
    } 
    public bool Equals(Person other) 
    { 
     return Name.Equals(other.Name); 
    } 
} 

, а затем использовать его так:

var newPersonList = new List<Person> 
{ 
    new Person("A"), 
    new Person("B"), 
    new Person("C") 
}; 
newPersonList.Remove("A"); 

Или даже так:

var newPersonList = new List<Person> { "A", "B", "C" }; 
newPersonList.Remove(new Person("A")); 
+3

Он может использовать 'newPersonList.RemoveAll (p => p.name ==" A ")'. Ваш подход должен проверять список дважды. Но лучше переопределить 'Equals' в' Person' или позволить ему реализовать 'IEquatable '. Затем 'Remove' работает так, как ожидалось. –

+0

@TimSchmelter Средняя сложность лучше для моего решения =) – astef

+0

@juharr Да, и даже если бы он был добавлен, его не удалять тогда ... – astef

1

Итак, вы хотите .net волшебно угадать, что по "A" строка вы имеете в виду поле name? Как это должно вывести его?

Я хотел бы предложить вам использовать словарь, если вы хотите работать вещи своим ключом (имя в данном случае):

var dict = new Dictionary<string, Person>() { 
    {"A", new Person("A")} 
} 

//and later 

dict.Remove("A"); 
+0

Это еще более волшебный, чем это, потому что это просто 'A', а не строка' 'A''. – juharr

+0

Я предполагаю, что он действительно имел в виду строку, иначе А не имеет никакого смысла. – Andrey

+0

Если вы хотите сделать классы сопоставимыми, вы используете словарь? Вам просто нужно предоставить метод, который используется для определения того, являются ли два объекта равными, равными 'Equals'. –

0

Вы не объявили А. Для того, чтобы сделать newPersonList.Remove(A);

Вы должны объявить объект Person A и добавить его в newPersonList

Person A = new Person("A"); 
newPersonList.Add(A); 
0

Как и другие сказали "Что такое A?". Если бы это была переменная, которая содержит Person, это будет работать.

void ABC() 
{ 
    var A = new Person("A"); 
    var B = new Person("B"); 
    var C = new Person("C"); 
    List<Person> newPersonList = new List<Person>(); 
    newPersonList.Add(A); 
    newPersonList.Add(B); 
    newPersonList.Add(C); 

    newPersonList.Remove(A); 
} 
Смежные вопросы