问题
Below is some linqpad test code. When this runs it errors because the second instance of "item" has a null list of subitems as opposed to an empty list.
I want to treat both situations (null or empty list) in exactly the same way but I wondered if there was a cleaner way than just putting a null check on the list and initialising an empty list when there's a null.
in other words, I could do this:
from si in (i.subitems == null ? new List<item>() : i.subitems)
but that's a little ugly and I wondered how I could improve on that?
public class item
{
public string itemname { get; set; }
public List<item> subitems { get; set; }
}
void Main()
{
List<item> myItemList = new List<item>()
{
new item
{
itemname = "item1",
subitems = new List<item>()
{
new item { itemname = "subitem1" },
new item { itemname = "subitem2" }
}
},
new item
{
itemname = "item2"
}
};
myItemList.Dump();
var res = (from i in myItemList
from si in i.subitems
select new {i.itemname, subitemname = si.itemname}).ToList();
res.Dump();
}
as a bonus question, can this same linq query be represented as a lambda and treat nulls the same way?
Cheers, Chris
回答1:
You could use the null coalescing operator
var res = (from i in myItemList
from si in i.subitems ?? new List<item>()
select new { i.itemname, subitemname = si.itemname }).ToList();
But I think you should just filter the empty ones out
var res = (from i in myItemList
where i.subitems != null
from si in i.subitems
select new { i.itemname, subitemname = si.itemname }).ToList();
As for a lambda version you could say
var res = myItemList.Where(x => x.subitems != null)
.SelectMany(
x => x.subitems.Select(
y => new { x.itemname, subitemname = y.itemname }
)
);
But the query syntax version is way more readble.
回答2:
from si in (i.subitems ?? new List<item>())
how about that?
回答3:
You could add an (evil) extension method to do the work for you
public static IEnumerable<T> EnsureNotEmpty<T>(this IEnumerable<T> enumerable) {
if ( enumerable == null ) {
return Enumerable.Empty<T>();
} else {
return enumerable;
}
}
回答4:
An additional method would be not to allow subitems to be null. You could make the item constructor so that it defaults subitem to an empty list and then not allow null in the subitem setter.
That of course assumes you have access to modify item.
The null coalescing operator is what you are looking for as pointed out by Hunter Daley
来源:https://stackoverflow.com/questions/2201891/how-do-i-treat-null-lists-like-empty-lists-in-linq