C# 如何使用流畅的断言比较对象图中的嵌套列表

C# 如何使用流畅的断言比较对象图中的嵌套列表,c#,testing,nunit,fluent-assertions,C#,Testing,Nunit,Fluent Assertions,如果我有一个包含列表的预期对象图,如下所示: var expectedExperiment = new Experiment { Number= "12345", AllocatedInstrument = "Instrument 1", Experimenters = new List<Experimenter> { new

如果我有一个包含列表的预期对象图,如下所示:

        var expectedExperiment = new Experiment
        {
            Number= "12345",
            AllocatedInstrument = "Instrument 1",
            Experimenters = new List<Experimenter>
            {
                new Experimenter
                {
                    Name = "Sue"
                    Role = "Scientist",
                    Id = 1,
                    Initials = "S"
                },
                new Experimenter()
                {
                    Name = "Mark",
                    Role = "Technician",
                    Id = 2,
                    Initials = "M"
                },
            }
        };
但我有一个例外:

System.ArgumentException : Expression <o.Experimenters.Select(e => e.Role)> cannot be used to select a member.
System.ArgumentException:Expression e.Role)>不能用于选择成员。

在这种情况下,我不介意子项的顺序,但我想声明我关心的属性符合预期。

您可以通过检查当前对象的运行时类型和所选成员路径来做到这一点:

.Including(subjectInfo => subjectInfo.RuntimeType == typeof(Experimenter) &&
                          subjectInfo.SelectedMemberPath.EndsWith("Role"))
可将其提取到方法中以供进一步重用:

private Expression<Func<ISubjectInfo, bool>> BuildMemberExpression<TSource, TProperty>(Expression<Func<TSource,TProperty>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new NotSupportedException();
        }

        return subjectInfo => subjectInfo.RuntimeType == typeof(TSource) && 
                              subjectInfo.SelectedMemberPath.EndsWith(memberExpression.Member.Name);
    }
private Expression<Func<ISubjectInfo, bool>> BuildMemberExpression<TSource, TProperty>(Expression<Func<TSource,TProperty>> propertySelector)
    {
        var memberExpression = propertySelector.Body as MemberExpression;
        if (memberExpression == null)
        {
            throw new NotSupportedException();
        }

        return subjectInfo => subjectInfo.RuntimeType == typeof(TSource) && 
                              subjectInfo.SelectedMemberPath.EndsWith(memberExpression.Member.Name);
    }
.Including(BuildMemberExpression((Experimenter e) => e.Name))
.Including(BuildMemberExpression((Experimenter e) => e.Role))