如何在 linq 中将空列表视为空列表?

发布于 2024-08-19 22:53:20 字数 1088 浏览 4 评论 0原文

下面是一些 linqpad 测试代码。运行时会出错,因为“item”的第二个实例具有空子项列表,而不是空列表。

我想以完全相同的方式处理这两种情况(空列表或空列表),但我想知道是否有一种更干净的方法,而不是仅仅在列表上进行空检查并在存在空时初始化空列表。

换句话说,我可以这样做:

from si in (i.subitems == null ? new List<item>() : i.subitems)

但这有点难看,我想知道如何改进?

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();
}

作为一个额外的问题,这个相同的 linq 查询可以表示为 lambda 并以相同的方式处理空值吗?

干杯,克里斯

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泛泛之交 2024-08-26 22:53:20

您可以使用 空合并运算符

var res = (from i in myItemList
           from si in i.subitems ?? new List<item>()
           select new { i.itemname, subitemname = si.itemname }).ToList();

但我认为您应该过滤空的

var res = (from i in myItemList
           where i.subitems != null
           from si in i.subitems
           select new { i.itemname, subitemname = si.itemname }).ToList();

至于 lambda 版本,你可以说

var res = myItemList.Where(x => x.subitems != null)
                    .SelectMany(
                        x => x.subitems.Select(
                            y => new { x.itemname, subitemname = y.itemname }
                        )
                     );

但是查询语法版本更具可读性。

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.

等待我真够勒 2024-08-26 22:53:20
from si in (i.subitems ?? new List<item>())

那怎么样?

from si in (i.subitems ?? new List<item>())

how about that?

你的往事 2024-08-26 22:53:20

您可以添加一个(邪恶的)扩展方法来为您完成这项工作

public static IEnumerable<T> EnsureNotEmpty<T>(this IEnumerable<T> enumerable) {
  if ( enumerable == null ) {
    return Enumerable.Empty<T>();
  } else { 
    return enumerable;
  }
}

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;
  }
}
糖粟与秋泊 2024-08-26 22:53:20

另一种方法是不允许子项为空。您可以创建项目构造函数,以便将子项目默认为空列表,然后在子项目设置器中不允许为 null。

当然,这是假设您有权修改项目。

正如 Hunter Daley 指出的那样,空合并运算符就是您正在寻找的

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文