Проверка, все ли значения равны нулю внутри инициализированного объекта

У меня есть код, который читает данные из листов 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();

Это вернет список всех объектов без нулей. Если вы хотите нули, удалите !, конечно.

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

Ух ты, мой ответ почти такой же, как у Мэтью Хаугена... оба должны работать нормально, хотя реализация немного отличается.

Другие вопросы по тегам