#c# #linq #list #reflection
#c# #linq #Список #отражение
Вопрос:
У меня есть объект со многими свойствами. Я создаю список этих объектов и отсеиваю плохие, находя случаи, когда важное свойство равно нулю или пусто. Нравится…
theList.RemoveAll(p => string.IsNullOrEmpty(p.ID));
Как я могу выполнить аналогичную проверку, но вместо проверки одного свойства проверьте, является ли какое-либо свойство в объекте NULLOREMPTY ?
Я работал с отражением, чтобы получить такие вещи, как
object x = typeof(MyObject).GetProperties().
Select(p => p.GetValue(exampleObject, null)).
Where(v => string.IsNullOrEmpty(v.ToString())));
но я недостаточно разбираюсь в этом, чтобы собрать все это вместе. Пожалуйста, объясните мне прямо.
Ответ №1:
проверьте, является ли какое-либо свойство объекта nulllorempty?
theList.RemoveAll(x => x.GetType().GetProperties()
.Select(p => p.GetValue(x, null))
.Any(p => p == null));
Комментарии:
1. В качестве примечания значение null в GetValue — это то место, куда вы должны поместить массив, указывающий индексы для индексированных свойств. Если для вашего объекта есть какие-либо индексированные свойства, код вызовет исключение ArgumentException, если это значение равно нулю. Используйте PropertyInfo. GetIndexParameters() если он возвращает массив длиной 0, свойство не индексируется.
Ответ №2:
Таким образом, имеет смысл применять String.IsNullOrEmpty
только к строковым значениям, вы должны выбирать только свойства строкового типа:
List<MyObject> objects = new List<MyObject>();
// fill list
var stringProperties = typeof(MyObject)
.GetProperties()
.Where(p => p.PropertyType == typeof(string))
.ToArray();
А затем получить отфильтрованную последовательность объектов:
var query = objects.Where(o =>
stringProperties.All(p => !String.IsNullOrEmpty((string)p.GetValue(o))));
Вы можете использовать тот же подход для удаления объектов из списка:
objects.RemoveAll(o =>
stringProperties.Any(p => String.IsNullOrEmpty((string)p.GetValue(o))));