select 如何在 Aggregate 函数中使用 2 class 导出 props

How select derived props in Aggregate function with 2 class

请帮助 System.Linq.Aggregate

我有以下class

public class MainClass
{
   public ClassA someProp { get; set; }
   public ClassA someProp2 { get; set; }
}

public class ClassA
{
   public virtual Type Types => Type.None;
}

public class ClassB:ClassA
{
   public override Type Types => Type.Default;
        
   public string FieldName { get; set; }
}

public class ClassC:ClassA
{
   public override Type Types => Type.Value;
        
   public int FieldValue { get; set; }
}

如果 FieldName 在 ClassB 中填充,我想获取它;如果它也为 someProp2 和 someProp 填充,我想获取 ClassC 中的值

我了解如何获得 1 个值

//for get name
    IEnumerable<string> values = entities
    .Where(x=>x.someProp!=null || x.someProp2!=null)
    .SelectMany(mainClass => new[] {mainClass.someProp,mainClass.someProp2 })
    .OfType<ClassB>()
    .Select(classB => classB.FieldName)
//for get value
IEnumerable<int> values = entities
    .Where(x=>x.someProp!=null || x.someProp2!=null)
    .SelectMany(mainClass => new[] {mainClass.someProp,mainClass.someProp2 })
    .OfType<ClassC>()
    .Select(classC => classC.FieldValue)

但是我不明白如何在1个请求中获取2个值,因为会有类型2 classes ClassB and ClassC

最好的方法可能是通过聚合方法!

告诉我如何制定选​​择条件和聚合方法本身

如果您想使用 .Aggregate() 来实现您的目标,我建议您在展平 属性 对后使用 overload that lets you define a seed in addition to the accumulator function

可以这样实现:

IEnumerable<string> values = entities
    .SelectMany(ent => new[] { ent.someProp, ent.someProp2 })
    .Aggregate(new List<string>(),
        ( fields, property ) => 
        {
            if (property is ClassB)
            {
                fields.Add(((ClassB)property).FieldName);
            }
            else if (property is ClassC)
            {
                fields.Add(((ClassC)property).FieldValue.ToString());
            }
            
            return fields;
        });

在这里,我们的种子

new List<string>()

我们的累加器函数

( fields, property ) => 
{
    // accumulation logic
    return fields;
}

,包含累加器值参数fields和元素参数property

我们的种子是我们累加器值的初始值。对于扁平化的 属性 集合(由 .SelectMany() 提供)中的第一个 property,我们的累加器值 (fields) 因此是一个空字符串列表。

对于每个元素 (property),根据 属性 的 class 类型提取字段值:

  • 如果 propertyClassBFieldName 将被提取并添加到我们的累加器值中。
  • 如果property是一个ClassC,则提取FieldValue,并将其字符串值添加到我们的累加器值中。
  • (如果 property 不是那些 class,则不会向 fields 添加任何内容)。

有条件地向 fields 添加一个字段值后,fields 从累加器函数返回,用作累加器函数下一次迭代中的累加器值(即对于下一个 property 在展平的集合中)。


对于entities给出如下:

List<MainClass> entities = new()
{
    new() 
    { 
        someProp = new ClassC() { FieldValue = 4 },
        someProp2 = new ClassB() { FieldName = "Flower" } 
    },
    new() 
    { 
        someProp = new ClassA() { },
        someProp2 = new ClassC() { FieldValue = 7 } 
    }
};

,结果 values 将包含:

4
Flower
7

示例 fiddle here.