Вопрос по c#, asp.net – «List.Remove» в C # не удаляет элемент?

6

Здравствуйте, как я могу удалить элемент из общего списка, вот мой код, я пытаюсь сделать это правильно, но я не знаю, где я делаю ошибку; /

Users us_end = new Users();
foreach (var VARIABLE in ((List<Users>)Application["Users_On"]))
{
    if(VARIABLE.Id == (int)Session["Current_Id"])
    {
        us_end.Name = VARIABLE.Name;
        us_end.Id = VARIABLE.Id;
        us_end.Data = VARIABLE.Data;
    }
}
List<Users> us = ((List<Users>)Application["Users_On"]);
us.Remove(us_end);
Application["Users_On"] = us;
это действительно не имеет большого смысла: вы перезаписываете каждый объект Users, который вы создаете внутри этого foreach .. Thousand
Кроме того, ты бросилApplication["Users_On"] вList<Users, но позже установите его наUser. Это явно неправильно, это не может быть так, если вы хотите, чтобы этот код продолжал работа Ed S.
Ну, что не так, как ожидалось? (ДляRemove для работы предмета нужно правильно реализоватьEquals). user166390

Ваш Ответ

5   ответов
12

Тебе нужно удалить тот же объект, а не копию.

Users us_end;

foreach (var VARIABLE in ((List<Users>)Application["Users_On"]))
{
    if(VARIABLE.Id == (int)Session["Current_Id"])
    {
       us_end = (Users)VARIABLE;
       break;
    }
}

if (us_end != null)
{
    List<Users> us = ((List<Users>)Application["Users_On"]);
    us.Remove(us_end);
    Application["Users_On"] = us;
}

Редактировать

Просто чтобы уточнить адрес здесь, как указал pst, вы могли бы также реализоватьIEquatable interface и некоторые переопределения, такие как ответ Groo, чтобы заставить его работать, но я думаю, что это излишне по этой конкретной теме. Давать это как наиболее распространенную практику, но прояснить, что также возможно удалить элементы из списка, даже если они являются различными экземплярами или даже различными объектами с помощью такой техники.

Ref .:http: //msdn.microsoft.com/en-us/library/ms131187.asp

Потому что ответы «правильные», в том числе и этот, просто [изначально] вводящий в заблуждение :) Nit: Не нужно реализовыватьIEquatable as object.Equals (object) - помните, что это полиморфно! - все еще можно использовать. Я используюRemove и другие равно- Требуя методов и просто "ожидаю, что это сработает" при равенстве, которое я определил для моих типов То есть я бы ожидалa.Equals(b) работать так же, какl.Add(a); l.Remove(b) работает, и наоборот. user166390
Так почему ты не написал правильный ответ? если вы думаете, что настроены объяснить переопределение сравнения просто для удаления объекта из списка, сделайте это. Я понимаю вашу точку зрения, но, пожалуйста, сделайте свой собственный ответ и объясните его, чтобы он мог пометить его как правильный, а не падать на меня. rcdmk
6

Новый Users объект - это не то же самое, что любой объект уже вApplication["Users_On"] (у него будет другая ссылка), поэтому он не будет удален.

Это предполагает, чтоEquals и / илиIEquatable<T> не были переопределены / реализованы вUsers.

List<Users> us = ((List<Users>)Application["Users_On"]);
Users us_end = us.Where(u => u.Id == (int)Session["Current_Id"]).FirstOrDefault();
us.Remove(us_end);
Application["Users_On"] = us;

Кстати, ваши имена переменных не очень хороши - используйте более описательные имена.

НеRemove работаешь на равенство? user166390
Да, это работает на равенство и по умолчанию для объектов, равенство реализуется путем проверки ссылки ... Nitin Midha
@ pst - который для ссылочного типа будет ссылочным равенством. Oded
@ Одедclass Users { override Equals } ?? user166390
Не забудьте добавитьusing System.Linq; чтобы это сработало. rcdmk
0

Как насчет

List<Users> us = ((List<Users>)Application["Users_On"]);
Users us_end = us.First(x => x.ID == (int)Session["Current_Id"]);
us.Remove(us_end);
Application["Users_On"] = us;
0

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

List<Users> us = ((List<Users>)Application["Users_On"]);
us.Remove(us.FirstOrDefault(u => u.ID == (int)Session["Current_Id"]));
Application["Users_On"] = us;
9

равенство объектов сравнивается по ссылке в .NET (если неEquals переопределяется, каждый объект наследуется отobject.Equals). Если вы хотите, чтобыRemove метод, чтобы найти свой объект, вы не можете передать новый объект.

Самый простой способ - най фактический объект, который имеет желаемые свойства, а затем удалите его:

var id = (int)Session["Current_Id"];
var list = (List<Users>)Application["Users_On"];  

// find the exact item to remove.
var itemToRemove = list.FirstOrDefault(u => u.Id = id);

// if found, remove it
if (itemToRemove != null)
{
    list.Remove(itemToRemove);
}
НоEquals является виртуальным. Это не имеет смысла для меня. user166390
@ pst: виртуальный метод, если исключение не переопределено, ведет себя так, как определено в базовом классе.Object.Equals сравнивает по ссылке. Groo
Я могу принять это после обновления (раньше оно было неверным, поскольку определение «Пользователи» неизвестно). user166390

Похожие вопросы