Проверка, все ли значения равны нулю внутри инициализированного объекта
У меня есть код, который читает данные из листов Excel и помещает в список.
Теперь возникает сценарий, когда пользователь копирует некоторые действительные данные, затем оставляет много строк пустыми и снова копирует действительные данные. Это читает много пустых строк. Я использую какой-то старый код для чтения Excel, который может быть использован где-то еще, поэтому я не хочу с этим связываться.
Проблема в том, что у меня много объектов внутри List, которые инициализируются, но все значения имеют значение null. Так что я проверил все атрибуты, если вроде:
if (lstConsolidatedData != null)
{
foreach (var lst in lstConsolidatedData)
{
if(lst.a!=null && lst.b!=null && lst.c!=null //& so on....)
{
//some stuff...
}
}
}
Я знаю, что это не самый лучший или поддерживаемый способ, так как листы Excel могут быть изменены, и, таким образом, весь код списка столбцов необходимо снова и снова изменять для добавления или удаления одного столбца из Excel.
Есть ли способ проверить все значения внутри lst
для нуля в одном утверждении? что-то вроде lst.all !=null
Любая идея, если не код также будет работать для меня.
пожалуйста, обратите внимание lst==null
является false
РЕДАКТИРОВАТЬ: используя ответы снизу, я получаю эту ошибку
РЕДАКТИРОВАТЬ: o.GetType().GetProperties().Any(c => c.GetValue(o) == null)
работает для любого нуля, но я действительно хочу удалить строки, которые не содержат данных во всех столбцах, а не для одного или двух столбцов. Проблема не решена o.Item1 != null && ...
также, поскольку имя / количество столбцов часто меняется.
4 ответа
Я закончил копаться в старом коде и перед превращением набора данных в список я удалил пустые строки, используя код:
//Deleting empty records from Datset
foreach (DataTable source in result.Tables)
{
for (int i = 0; i < source.Rows.Count; i++)
{
DataRow currentRow = source.Rows[i];
bool isEmpty = false;
foreach (var colValue in currentRow.ItemArray)
{
if (!string.IsNullOrEmpty(colValue.ToString()))
{
isEmpty = false;
break;
}
else
isEmpty = true;
}
if (isEmpty)
source.Rows[i].Delete();
}
}
result.AcceptChanges();
Не забывай .AcceptChanges()
поскольку он фактически сохраняет изменения, сделанные в наборе данных, без которого не удаляются никакие записи.
Вы можете использовать отражение, чтобы сделать это, но имейте в виду, что оно несет потери производительности по сравнению с выполнением этого явно.
public bool IsAnyPropertyNull(object o)
{
return o.GetType().GetProperties().Any(c => c.GetValue(o) == null);
}
Однако нет встроенного выражения для уменьшения o.Item1 != null && o.Item2 != null && ...
введите синтаксис.
Кроме того, я предполагаю, что значения, о которых вы говорите, являются свойствами. Вы также можете использовать GetFields
или что вам нужно, если это более уместно.
Как отметил Мэтью Хуаген, использование отражений для получения свойств, а затем проверка их значений, похоже, хорошо. Тем не менее, это имеет большое предостережение: могут быть некоторые свойства, которые вы не хотите проверять. Чтобы решить эту проблему, вы можете либо поместить их в список (как упоминал Тим Шмельтер), либо вы можете украсить нужные свойства ConsolidatedData
с пользовательским атрибутом, чтобы различать их:
public class ConsolidatedData
{
public int Id { get; set; }
[NotNull]
public object PropertyOne { get; set; }
[NotNull]
public object PropertyTwo { get; set; }
}
public class NotNull : Attribute { }
Тогда проверка на ноль безопасна, когда вы отфильтровываете свойства, не имеющие NotNull
атрибут:
ConsolidatedData v = new ConsolidatedData();
bool allNotNull = v.GetType().GetProperties()
.Where(p => null != (Attribute.GetCustomAttribute(p, typeof(NotNull)) as NotNull))
.All(p=>p.GetValue(v) !=null );
Здесь недвижимость Id
не проверяется.
Вы можете написать метод расширения для вашего ConsolidatedData
как это;
public static bool IsAnyPropNull(this ConsolidatedData cdata)
{
return cdata.GetType().GetProperties().Any(p => p.GetValue(this) == null);
}
И тогда вы можете отфильтровать свой список с помощью одной строки;
var filteredList = lstConsolidatedData.Where(cd => !cd.IsAnyPropNull()).ToList();
Это вернет список всех объектов без нулей. Если вы хотите нули, удалите !
, конечно.
Редактировать;
Ух ты, мой ответ почти такой же, как у Мэтью Хаугена... оба должны работать нормально, хотя реализация немного отличается.