Lambda Expression +IEnumerable+ C#+ Where+Contains
In C#, I have an IEnumerable<Data>
named items
And Data
is a class that contains 3 string Attributes.
I want to get all items that attribute1 contains a string
public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items,string Filter)
{
return items.Where(item=>item.Attribute1.Contains(Filter));
}
It throws an exception, however when I use开发者_开发百科:
public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items,string Filter)
{
return items.Where(item=>item.Attribute1==Filter);
}
It works.
Did I miss something?
You should also actively filter out the results that have a null value for Attribute1
return items.Where(i => !String.IsNullOrEmpty(i.Attribute1) && i.Attribute1.Contains(filter));
When you create a variable of a type, unless you specify a value, it will have the default value for the type. There are two types in .NET reference types and value types. The default value for references types (anything created as a class) is null. A string is an example of a reference type.
public class Data
{
public string Attribute1 { get; set; }
public string Attribute2 { get; set; }
public string Attribute3 { get; set; }
}
The code above, all three attribute values are not initialized and have a value of NULL. To assign a value to the three attributes when create a new instance of your object with 'new Data()' you can create a constructor that assigns a value.
public Data()
{
Attribute1 = Attribute2 = Attribute3 = String.Empty();
}
Now all attributes will have the empty string value. Meaning they are initialized but don't have a value.
Value types (anything defined as a struct) can not be NULL. Examples of this are DateTime
, int
, double
, decimal
, etc. The default value for number types is 0. The default value for DateTime
is DateTime.MinValue
.
I assume the value of Attribute1 was null then calling .Contains will crash and == will not.
Some of your Attribute1
s are probably null.
You can't call Contains
on null
.
Consdider this:
public IEnumerable<Data> getDataFiltered(IEnumerable<Data> items, string Filter){
return items.Where(item => item != null && item.Contains(Filter));
}
I added the nullity checks to make sure that Contains
isn't called on null reference. String
is a reference type which means that it can occasionaly be null.
If you want to check for the exact value use == if you want to check for the occurence of a string use either of the following.
For a case sensitive approach the following :-
items.Where(item => (item ?? "").Contains(Filter));
?? is the coalesc operator in c# just like sql's ie the first non value
Contains however is case sensitive so if this is not desired then the following might be what you want.
items.Where(item => -1 != (item ?? "").IndexOf(Filter, StringComparison .InvariantCultureIgnoreCase));
精彩评论