【问题标题】:Loop through objects properties in an object循环遍历对象中的对象属性
【发布时间】:2021-11-20 20:55:13
【问题描述】:

我有一个像下面这样的对象

public class MainObj 
{
    public int BankDetailPercentage { get; set; }
    public int PersonalDetailPercentage { get; set; }
    public BankDetail BankDetail { get; set; }
    public PersonalDetail PersonalDetail { get; set; }
}
public class BankDetail
{
    public string Name { get; set; }
    public string Branch { get; set; }
    public string AccountNumber { get; set; }
}
public class PersonalDetail
{
    public string Name { get; set; }
    public string address { get; set; }
}

我需要遍历该 MainObj 对象并找到填充了多少 BankDetail 和 PersonalDetail 对象的属性,并在此基础上设置 MainObj 对象的 BankDetailPercentage 和 PersonalDetailPercentage 字段中填充属性的百分比并返回它。我该如何做到这一点,我在下面尝试过,但无法做到这一点

    public MainObject calculatePercentage(MainObject mainObject) 
    {
        int bdCount = 0, pdCount = 0, bdTotal = 3, pdTotal = 2;

        PropertyInfo[] properties = typeof(MainObject).GetProperties();
        foreach (var property in properties)
        {
            var value = property.GetValue(mainObject);
            if (property.Name == "BankDetail")
            {
              //
            }
        }
        return mainObject;
    }

【问题讨论】:

  • 是否有令人信服的理由使用反射来完成这项任务,而不是简单地检查每个 BankDetail 和 PersonalDetail 的单独值?
  • @AndrewH 不是真的,但问题是这个 MainObj 有许多类似的对象,如 BankDetail 和 PersonalDetail 有很多属性,我想检查各个值会非常乏味。
  • 反射应该保留用于特殊情况,因为它具有检查每个单独属性(虽然乏味)没有的性能影响。我认为您将花费更多时间编写带有反射的代码,以尝试解决您的问题并在您的数据合约发生变化并且您有令人困惑的反射代码要更新时产生未来的技术债务。简单的解决方案是花时间检查您真正关心的值是否不为空,或者添加其他属性来跟踪是否已填充所有必需值并且可以简单地检查这些值。

标签: c# .net loops object reflection


【解决方案1】:

首先,您需要获取相关对象的实例(您已在上面的代码中完成。

var value = property.GetValue(mainObject);

然后您需要计算该对象中包含多少属性。为此,我们需要先获取属性。

var subProperties = property.PropertyType.GetProperties();
var propertyCount = subProperties.Length;

现在我们需要检查每个属性以查看是否设置了值。

var populatedCount = 0;

foreach (var subProperty in subProperties)
{
    if (!string.IsNullOrEmpty(subProperty.GetValue(value)))
    {
        populatedCount++;
    }
}

然后取百分比。

var percentage = (float)populatedCount / propertyCount;

【讨论】:

  • 太棒了,它就像一个魅力,我用“property.PropertyType.BaseType.Name”来检查它是否是我正在处理的对象,谢谢一百万:)
  • 乐于助人。除了按名称比较之外,您还可以通过if (property.PropertyType is MyType) ex 来检查类型是否是您所指的类型。 if (property.PropertyType is BankDetail) 这样您就不会被绑定到使用这些类的类中的特定命名。
  • 我不应该只使用if (property.PropertyType.IsClass) 来检查它是否是一个对象,然后才继续检查子属性吗?
  • 我建议您不要使用名称的字符串比较,而是使用有问题的类型(例如 BankDetails)和属性类型。目前在技术上没有区别,但是如果您以不同的方式命名属性或更改其名称,则字符串比较将失败,而类型检查则不会。对您当前正在做的事情没有任何伤害,只是不安全。
  • 至于IsClass,您可以使用它,但仍然需要进行类型检查或名称比较,因此最终它不会真正完成任何事情。反射的开销已经很高,小的微优化并不重要(除非在一个紧密的循环中)
猜你喜欢
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 2016-09-09
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多