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

问题描述

我有以下课程

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

然后我有下面的“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 只给出一个对象而不是串联对象列表。

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

任何人都可以让我知道如何实现这一点,非常感谢。

解决方法

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;
}
,

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

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

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

在一个循环中,你反复进行这个分配 equipmentResults = equipmentRedundancies.Concat(componentList);

也就是说:将equipmentResultscomponentList的串联分配给equipmentRedundancies

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

因此,每次通过循环时,您都会分配一个新的 IEnumerable,它描述一个空列表的串联,后跟您通过反射检索到的属性 equipmentResults。然后最后返回空列表和检索到的属性的这些串联中的最后一个。

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