【问题标题】:Looping through Generic Class's collection property循环遍历泛型类的集合属性
【发布时间】:2017-07-21 17:08:50
【问题描述】:

尽管已经发布了许多问题,但似乎没有一个对我的问题有帮助。

我已经开始了新的 Generics / Reflection 冒险,我只是想了解语法和概念。

我有一个 Generic 类,其中有 X 个属性,其中一个是一个集合,一切正常,但我在按属性名称从集合 props 中提取值时遇到问题。

foreach (var property in typeof(T).GetProperties())
{
    if (property.Name == "Props")
    {
        foreach (var item in (IEnumerable)property.GetValue(type, null))
        {
            var propertyName = "";
            var newValue = "";
            var oldValue = "";

            sbDescription.AppendLine(strDescriptionVals
               .Replace("{0}", (item.ToString() == "PropertyName") ? item.ToString() : "" + ", "));

            sbAllNotes.AppendLine(strAllNotes
               .Replace("{0}", (item.ToString() == "PropertyName") ? item.ToString() : "")
               .Replace("{1}", (item.ToString() == "NewValue") ? item.ToString() : "")
               .Replace("{2}", (item.ToString() == "OldValue") ? item.ToString() : ""));
        }
    }
}

如您所见,我已经确定了属性 Props,现在我想遍历它并按属性名称提取值。

item.ToString() 只打印类属性的命名空间,而不是值

希望各位好心人能给我指明正确的方向?

【问题讨论】:

  • 什么是type 变量?
  • @Sybren 它的 (T) 属性在每个方法调用上都几乎相同,这就是它是通用的原因。
  • 这是一组非常“匿名”的特性和类。问题只是从“集合属性”中检索值而已。
  • 有人有什么想法吗?
  • 那么你的收藏到底是什么类型的?列表、IList、ICollection?你的变量“类型”是什么?这应该是您希望从中获得属性值的对象实例。

标签: c# generics reflection


【解决方案1】:

您可能希望递归地“深入”到项目属性中。

注意,只是概念性代码片段,不保证我在这里写的那样有效:

void Print(object value, string propertyName)
{
    if (property.PropertyType == typeof(string) || property.PropertyType.IsPrimitive)
    {
      sbAllNotes.AppnedLine(.. propertyName .. value ..);
    }
    else if ((typeof(IEnumerable).IsAssignableFrom(property.PropertyType)
    {
      PrintCollectioType((IEnumerable)value);
    }
    else
    {
      PrintComplexType(value);
    }
}

void PrintCollectioType(IEnumerable collection)
{
  foreach (var item in collection) 
  {
    Print(item, "Collection Item");
  }
}

void PrintComplexType(IEnumerable collection)
{
  foreach(var property in owner.GetType().GetProperties())
  {
    var propertyName = property.Name;
    var propertyValue = property.GetValue(owner);
    Print(item, propertyName);
  }
}

要打印“道具”,请执行以下操作:

var props = typeof(T).GetProperty("Props");
var propsValue = props.GetValue(rootObject);
Print(propsValue, "Root");

【讨论】:

    【解决方案2】:

    在玩了代码并进一步了解了逻辑之后,我突然想到就像Props迭代中的“获取类型和属性”一样简单:

            //Get the collection property
            foreach (var property in typeof(T).GetProperties())
            {
                if (property.Name == "Props")
                {
                    foreach (var item in (IEnumerable)property.GetValue(type, null))
                    {
                        //Because props is a collection, Getting the type and property on each pass was essential
                        var propertyName = item.GetType().GetProperty("PropertyName").GetValue(item, null);
                        var newValue = item.GetType().GetProperty("NewValue").GetValue(item, null);
                        var oldValue = item.GetType().GetProperty("OldValue").GetValue(item, null);
    
                       sbDescription.AppendLine(strDescriptionVals
                           .Replace("{0}", (propertyName != null) ? propertyName.ToString() : "" + ", "));
    
                       sbAllNotes.AppendLine(strAllNotes
                           .Replace("{0}", (propertyName != null) ? propertyName.ToString() : "")
                           .Replace("{1}", (newValue != null) ? newValue.ToString() : "")
                           .Replace("{2}", (oldValue != null) ? oldValue.ToString() : ""));
                    }
                }
            } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 2016-07-16
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多