Список <объект>.RemoveAll - Как создать соответствующий Предикат

Это - немного вопроса о новичке - я все еще довольно плохо знаком с C# и дженериками и абсолютно плохо знаком с предикатами, делегатами и лямбда-выражениями...

У меня есть класс 'Запросы', который содержит универсальный список другого класса под названием 'Механизмы'. Я создаю код для добавления/редактирования/удаления Механизмов от родительского Запроса. И в данный момент, я конкретно смотрю на удаления.

Из того, что я читал до сих пор, кажется, что я могу использовать Механизмы. RemoveAll () для удаления объекта с конкретным VehicleID или всех объектов с конкретным EnquiryID. Моя проблема понимает, как подать.RemoveAll правильный предикат - примеры, которые я видел, слишком упрощенны (или возможно я слишком упрощен, учитывая свое отсутствие знаний предикатов, делегатов и лямбда-выражений).

Таким образом, если у меня был a List<Of Vehicle> Vehicles где каждый Механизм имел EnquiryID, как я использовал бы Vehicles.RemoveAll() удалить все механизмы для данного EnquiryID?

Я понимаю, что существует несколько подходов к этому так, я стремился бы услышать различия между подходами - так, как я должен получить что-то работа, это - также осуществление изучения.

Как дополнительный вопрос, действительно ли Универсальный список является лучшим репозиторием для этих объектов? Мой первый наклон был к Набору, но кажется, что я устарел. Конечно, Дженерики, кажется, предпочтены, но мне любопытно относительно других альтернатив.

42
задан Cœur 13 February 2017 в 15:44
поделиться

3 ответа

Методы RemoveAll () принимают делегат Predicate (пока здесь ничего нового). Предикат указывает на метод, который просто возвращает истину или ложь. Конечно, RemoveAll удалит из коллекции все экземпляры T , которые возвращают True с примененным предикатом.

C # 3.0 позволяет разработчику использовать несколько методов для передачи предиката методу RemoveAll (и не только этому…). Вы можете использовать:

Лямбда-выражения

vehicles.RemoveAll(vehicle => vehicle.EnquiryID == 123);

Анонимные методы

vehicles.RemoveAll(delegate(Vehicle v) {
  return v.EnquiryID == 123;
});

Обычные методы

vehicles.RemoveAll(VehicleCustomPredicate);
private static bool
VehicleCustomPredicate (Vehicle v) {
    return v.EnquiryID == 123; 
}
86
ответ дан 26 November 2019 в 23:27
поделиться

Это должно сработать (где enquiryId - идентификатор, с которым вам нужно сравнить):

vehicles.RemoveAll(vehicle => vehicle.EnquiryID == enquiryId);

Что это делает, так это передает каждое транспортное средство в списке в лямбда-предикат, оценивая предикат. Если предикат возвращает true (т.е. vehicle.EnquiryID == enquiryId), то текущий автомобиль будет удален из списка.

Если вы знаете типы объектов в ваших коллекциях, то использование общих коллекций - лучший подход. Это позволяет избежать приведения при извлечении объектов из коллекций, но также можно избежать боксирования, если элементы коллекции являются типами значений (что может вызвать проблемы с производительностью).

6
ответ дан 26 November 2019 в 23:27
поделиться

Предикат в T - это делегат, который принимает T и возвращает логическое значение. List .RemoveAll удалит все элементы в списке, в котором вызов предиката возвращает true. Самый простой способ предоставить простой предикат - это обычно лямбда-выражение , но вы также можете использовать анонимные методы или фактические методы.

{
    List<Vehicle> vehicles;
    // Using a lambda
    vehicles.RemoveAll(vehicle => vehicle.EnquiryID == 123);
    // Using an equivalent anonymous method
    vehicles.RemoveAll(delegate(Vehicle vehicle)
    {
        return vehicle.EnquiryID == 123;
    });
    // Using an equivalent actual method
    vehicles.RemoveAll(VehiclePredicate);
}

private static bool VehiclePredicate(Vehicle vehicle)
{
    return vehicle.EnquiryID == 123;
}
15
ответ дан 26 November 2019 в 23:27
поделиться
Другие вопросы по тегам:

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