尝试使用反射来连接对象列表

Trying to use reflection to concatenate lists of objects

我有以下class

public class HydronicEquipment
{
    public List<LibraryHydronicEquipment> Source { get; set; }
    public List<LibraryHydronicEquipment> Distribution { get; set; }
    public List<LibraryHydronicEquipment> Terminals { get; set; }
}

然后我有下面的 class 用于“libraryHydronicEquipment”

public class LibraryHydronicEquipment : IEquipmentRedundancy
{
    public string Name { get; set; }
    public RedundancyStatus RedundancyStatus { get; set; }
    public EquipmentRedundancy EquipmentRedundancy { get; set; }
 }

我正在尝试连接“LibraryHydronicEquipment”对象的列表,这些对象可从源、分发和终端的所有三个属性(即)和通用连接方法中获得,如下所示以下

 var source = hydronicEquipment.Source;
 var distribution = hydronicEquipment.Distribution;
 var teriminals = hydronicEquipment.Terminals;
 Source.Concat(Distribution).Concat(Terminals)

我正在尝试使用反射实现相同的效果,代码如下所示

 foreach (var (systemName, hydronicEquipment) in hydronicSystemEquipment)
 {
     bool isFirstSystem = true;                   
     var equipmentList = new List<string> { "Source", "Distribution", "Terminals" };
     var redundancyequipmentList = GetRedundancyEquipment(hydronicEquipment, equipmentList);                                  
  }

方法 GetRedundancyEquipment 如下所示

private static IEnumerable<IEquipmentRedundancy> GetRedundancyEquipment(HydronicEquipment hydronicEquipment, List<string> equipmentList)
{
    IEnumerable<IEquipmentRedundancy> equipmentRedundancies = new List<IEquipmentRedundancy>();
    dynamic equipmentResults = null;
    foreach(var equipment in equipmentList)
    {
        var componentList = hydronicEquipment.GetType().GetProperty(equipment).GetValue(hydronicEquipment, null) as IEnumerable<IEquipmentRedundancy>;
       equipmentResults =  equipmentRedundancies.Concat(componentList);
    }
    return equipmentResults;
}

这里的问题是即使我有 Source 有对象列表并且 Distribution 有对象列表,equipmentResults 只给出一个对象而不是串联对象列表。

我正在尝试 return 最后 IEnumerable<IEquipmentRedundancy> 使用反射方法,但它似乎不适用于上述代码。

任何人都可以告诉我如何实现这一点,非常感谢。

如果我们看看您在 GetRedundancyEquipment() 中所做的事情,就会变得很清楚。

首先你创建equipmentRedundancies = new List<IEquipmentRedundancy>();

然后你永远不会修改equipmentRedundancies - 例如通过 Add()。在超出范围并被垃圾收集之前,它一直是一个空列表。

在一个循环中你然后重复这个赋值equipmentResults = equipmentRedundancies.Concat(componentList);

也就是说:将componentListequipmentRedundancies的串联赋值给equipmentResults

请注意,Concat() 是一种延迟计算的 linq 方法。当您实际枚举它时,就会产生结果。它没有修改任何东西,更像是描述如何产生一个序列。

因此,每次通过循环,您都会分配一个新的 IEnumerable,它描述一个空列表的串联,后跟您通过反射检索到 equipmentResults 的 属性。然后在最后你 return 这些空列表的最后一个连接并检索 属性.

如果你想把它们全部放在一起,你应该将它们中的每一个连接到前一个连接的结果,而不是一个空列表。

GetRedundancyEquipment 应该保留您的值,而不是在每次迭代时重新分配引用。这是固定版本:

private static IEnumerable<IEquipmentRedundancy> GetRedundancyEquipment(HydronicEquipment hydronicEquipment, List<string> equipmentList)
{
    IEnumerable<IEquipmentRedundancy> equipmentRedundancies = new List<IEquipmentRedundancy>();
    var equipmentResults = new List<IEquipmentRedundancy>();
    foreach (var equipment in equipmentList)
    {
        var componentList = hydronicEquipment.GetType().GetProperty(equipment).GetValue(hydronicEquipment, null) as IEnumerable<IEquipmentRedundancy>;
        equipmentResults.AddRange(equipmentRedundancies.Concat(componentList));
    }
    return equipmentResults;
}