Лямбда-выражение + IEnumerable + C # + Где + Содержит - PullRequest
0 голосов
/ 29 марта 2011

Я думаю, что мой вопрос прост, Я ноб в C #. У меня есть IEnumerable<Data> с именем items И Data - это класс, который содержит 3 строковых атрибута.

Вот вопрос, который я хочу получить для всех элементов, которые attribute1 содержит строку

public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items,string Filter)
{
    return items.Where(item=>item.Attribute1.Contains(Filter));
}

выдает исключение, однако, когда я использую:

public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items,string Filter)
{
    return items.Where(item=>item.Attribute1==Filter);
}

Работает

Я что-то пропустил?

Ответы [ 5 ]

2 голосов
/ 29 марта 2011

Вы также должны активно отфильтровать результаты, которые имеют нулевое значение для атрибута1

return items.Where(i => !String.IsNullOrEmpty(i.Attribute1) && i.Attribute1.Contains(filter));

Когда вы создаете переменную типа, если вы не укажете значение, оно будет иметь значение по умолчанию для типа. В ссылочных типах .NET и типах значений есть два типа. Значение по умолчанию для ссылочных типов (что-либо созданное как класс) является нулевым. Строка является примером ссылочного типа.

public class Data
{
    public string Attribute1 { get; set; }
    public string Attribute2 { get; set; }
    public string Attribute3 { get; set; }
}

Приведенный выше код, все три значения атрибута не инициализируются и имеют значение NULL. Чтобы назначить значение трем атрибутам при создании нового экземпляра вашего объекта с помощью 'new Data ()', вы можете создать конструктор, который присваивает значение.

public Data()
{
    Attribute1 = Attribute2 = Attribute3 = String.Empty();
}

Теперь все атрибуты будут иметь пустое строковое значение. Это означает, что они инициализированы, но не имеют значения.

Типы значений (все, что определено как структура) не могут быть NULL. Примерами этого являются DateTime, int, double, decimal и т. Д. Значение по умолчанию для числовых типов равно 0. Значение по умолчанию для DateTime равно DateTime.MinValue.

2 голосов
/ 29 марта 2011

Некоторые из ваших Attribute1, вероятно, нулевые.

Вы не можете позвонить Contains на null.

2 голосов
/ 29 марта 2011

Я предполагаю, что значение Attribute1 было нулевым, тогда вызов .Contains завершится сбоем, а == - нет.

0 голосов
/ 29 марта 2011

Если вы хотите проверить точное значение, используйте ==, если вы хотите проверить наличие строки, используйте одно из следующих:

Для подхода с учетом регистра следующее: -

items.Where(item => (item ?? "").Contains(Filter));

??является оператором coalesc в c # точно так же, как и sql, т. е. первое не значение

Содержит, однако, чувствительно к регистру, поэтому, если это нежелательно, то может быть следующее:

items.Where(item => -1 != (item ?? "").IndexOf(Filter, StringComparison .InvariantCultureIgnoreCase));
0 голосов
/ 29 марта 2011

Рассмотрим это:

public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items, string Filter){

    return items.Where(item => item != null && item.Contains(Filter));
}

Я добавил проверки недействительности, чтобы убедиться, что Contains не вызывается при нулевой ссылке. String является ссылочным типом, что означает, что иногда он может быть нулевым.

...