c# - LINQ SelectMany 和 Where 扩展方法忽略空值

标签 c# linq .net-4.0 linq-to-objects

我有下面的示例代码,我很想知道如何使它更清晰,可能是通过更好地使用 SelectMany()。此时 QuestionList 属性不会为 null。我想要的只是一个 answerRows 列表,它们不是 null,但 Questions 有时也可以是 null

IEnumerable<IQuestion> questions = survey.QuestionList
                    .Where(q => q.Questions != null)
                    .SelectMany(q => q.Questions);
            
if(questions == null)
return null;

IEnumerable<IAnswerRow> answerRows = questions
                    .Where(q => q.AnswerRows != null)
                    .SelectMany(q => q.AnswerRows);

if(answerRows == null)
return null;

我对 Jon 关于 Enumerable.SelectMany 和 Null 的评论很感兴趣。 所以我想用一些假数据来尝试我的例子,以便更容易地看到错误在哪里,请看下面,特别是我如何使用 SelectMany()SelectMany( ),现在我更清楚了问题是必须确保您不对空引用使用 SelectMany(),当我实际阅读 NullReferenceException< 时很明显 name :( 最后把东西放在一起。

此外,在执行此操作时,我意识到在此示例中使用 try { } catch() { } 是无用的,并且像往常一样 Jon Skeet 有 answer :) 延迟执行..

因此,如果您想查看第 2 行的异常,请注释掉第 1 行的相关位 :P,抱歉,如果不重写代码示例,我不知道如何停止此错误。

using System;
using System.Collections.Generic;
using System.Linq;

namespace SelectManyExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var questionGroupList1 = new List<QuestionGroup>() {
                new QuestionGroup() {
                    Questions = new List<Question>() {
                        new Question() {
                            AnswerRows = new List<AnswerRow>() {
                                new AnswerRow(),
                                new AnswerRow()
                            }
                        },

                        // empty question, causes cascading SelectMany to throw a NullReferenceException
                        null,

                        new Question() {
                            AnswerRows = new List<AnswerRow>() {
                                new AnswerRow() {
                                    Answers = new List<Answer>() {
                                        new Answer(),
                                        new Answer()
                                    }
                                }
                            }
                        }
                    }
                }
            };

            var questionGroupList2 = new List<QuestionGroup>() {
                null,
                new QuestionGroup()
            };

            IEnumerable<AnswerRow> answerRows1 = null;
            IEnumerable<AnswerRow> answerRows2 = null;

            try
            {
                answerRows1 = questionGroupList1
                    .SelectMany(q => q.Questions)
                    .SelectMany(q => q.AnswerRows);
            }
            catch(Exception e) {
                Console.WriteLine("row 1 error = " + e.Message);
            }

            try
            {
                answerRows2 = questionGroupList2
                    .SelectMany(q => q.Questions)
                    .SelectMany(q => q.AnswerRows);
            }
            catch (Exception e)
            {
                Console.WriteLine("row 2 error = " + e.Message);
            }


            Console.WriteLine("row 1: " + answerRows1.Count());
            Console.WriteLine("row 2: " + answerRows2.Count());
            Console.ReadLine();
        }


    }

    public class QuestionGroup {
        public IEnumerable<Question> Questions { get; set; }
    }

    public class Question {
        public IEnumerable<AnswerRow> AnswerRows { get; set; }
    }

    public class AnswerRow {
        public IEnumerable<Answer> Answers { get; set; }
    }

    public class Answer {
        public string Name { get; set; }
    }
}

最佳答案

survey.QuestionList
    .Where(l => l.Questions != null)
    .SelectMany(l => l.Questions)
    .Where(q => q != null && q.AnswerRows != null)
    .SelectMany(q => q.AnswerRows);

我建议您确保您的集合永远不会 null。如果处理不好,null 可能会有点麻烦。您的代码中到处都是 if (something != null) {}。然后使用:

survey.QuestionList
    .SelectMany(l => l.Questions)
    .SelectMany(q => q.AnswerRows);

关于c# - LINQ SelectMany 和 Where 扩展方法忽略空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14469159/

相关文章:

c# - 将 DateTime 转换为 unix 时间戳并再次转换回来 - 结果不相等

c# - .Net BinaryWriter 在检查流位置时自动刷新流

.net - 2条linq语句可以变成1条吗?

c# - Microsoft 图表控件 : how to set chart width to width of surrounding div?

c# - 如何将数据从 C# 传递到 Bartender2016

c# - 从两个相同结构的表获取mysql查询

c# - 使用 LINQ,如何将 List<List<string>> 转换为 List<string>?

c# - 如何用linq获取相关数据?

.net-4.0 - .NET 4.0 线程.任务

asp.net - 对我自己的表使用表单例份验证