【问题标题】:Trying to use reflection to concatenate lists of objects尝试使用反射来连接对象列表
【发布时间】:2021-05-20 22:12:46
【问题描述】:

我有以下课程

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&lt;IEquipmentRedundancy&gt;,但它似乎不适用于上述代码。

谁能告诉我如何实现这一点,非常感谢。

【问题讨论】:

  • 当你说“只给一个对象”时,它给了你什么对象?
  • 它只是给单个IEquipmentRedundancy 反过来它正在发送最后一个对象
  • 添加只读属性怎么样public class HydronicEquipment { public List&lt;LibraryHydronicEquipment&gt; Source { get; set; } public List&lt;LibraryHydronicEquipment&gt; Distribution { get; set; } public List&lt;LibraryHydronicEquipment&gt; Terminals { get; set; } public List&lt;LibraryHydronicEquipment&gt; AllSources { get { return Source.Concat(Distribution).Concat(Terminals) } } }
  • @RodRamírez,我正在尝试使用反射来实现
  • @EnigmaState 检查我上面的评论

标签: c# .net linq reflection c#-7.0


【解决方案1】:

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

首先你创建equipmentRedundancies = new List&lt;IEquipmentRedundancy&gt;();

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

在一个循环中,您然后重复进行此分配equipmentResults = equipmentRedundancies.Concat(componentList);

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

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

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

如果您希望将它们全部连接在一起,则应将它们中的每一个连接到前一个连接的结果,而不是连接到一个空列表。

【讨论】:

  • 是的,谢谢,这就是我要寻找的东西,但是如何获取以前的串联列表是我遇到的问题。你能有任何你想扔的样本sn-p吗?
  • @EnigmaState ...您已经将结果分配给 IEnumerable。只需使用它 - 而不是列表。事实上,我会说根本不要使用列表。如果您没有将列表用作列表,而只是作为某些 linq 组合的空起点,请使用 Enumerable.Empty&lt;T&gt;()
  • 好的,你的意思是这个equipmentRedundancies.Concat(componentList);,但我需要在方法结束时返回连接列表,并得到警告,因为不返回连接对象
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多