循环遍历泛型类的集合属性

4

虽然有很多问题被发布,但似乎没有帮助我解决我的问题。

我开始了一个新的 泛型 / 反射 的探险,我只是试图理解语法和概念。

我有一个 泛型 类,其中包含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
@Sybren,它的(T)属性在每个方法调用中基本相同,这就是为什么它是通用的。 - Tez Wingfield
这是一组非常“匿名”的特性和类。问题在于从“集合属性”中检索值,仅此而已。 - Tez Wingfield
有人有任何想法吗? - Tez Wingfield
你的集合到底是什么类型?List<T>、IList<T>、ICollection?而你的变量“type”又是什么呢?它应该是你想要获取属性值的对象实例。 - Waescher
你能展示一下类型 T 的类定义吗? - PaulF
2个回答

3

您可能想要递归地“潜入”项目的属性。

注意,这里只提供概念性的代码片段,无法保证其与我在这里编写的完全一致。

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

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

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

1

在玩弄代码并更好地理解逻辑后,我意识到这只是在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() : ""));
                }
            }
        } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接