循环遍历没有反射的对象属性

时间:2013-12-11 14:48:20

标签: c# for-loop foreach

我有MyModel类和MyModel的一些对象。

我需要没有反射的对象的for-loop或foreach属性。如何实施?

类示例:

public class MyModel
{
    public string Level1_TypeName { get; set; }
    public string Level1_AttrType { get; set; }
    public string Level1_AttrValue { get; set; }
    public string Level2_TypeName { get; set; } 
    public string Level2_AttrType { get; set; }
    public string Level2_AttrValue { get; set; }
    public string Level3_TypeName { get; set; } 
    public string Level3_AttrType { get; set; }
    public string Level3_AttrValue { get; set; }
    public string Level4_TypeName { get; set; } 
    public string Level4_AttrType { get; set; }
    public string Level4_AttrValue { get; set; }
    public string Level5_TypeName { get; set; } 
    public string Level5_AttrType { get; set; }
    public string Level5_AttrValue { get; set; }
    public string Level6_TypeName { get; set; }  
}

4 个答案:

答案 0 :(得分:11)

强烈建议你采取两项行动:

  • 创建新类型以封装TypeNameAttrTypeAttrValue
  • 的组合
  • 更改模型以包含该类的集合,而不是几个单独的属性。

此时,在不使用反射的情况下迭代属性将非常容易......而且您的代码也会更加清晰。

答案 1 :(得分:3)

您可以使用反射制作包含所有值的字典:

var obj = new MyModel();
var dictionary = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(p => p.Name, p => p.GetGetMethod().Invoke(obj, null));
foreach (var kv in dictionary)
    Console.WriteLine(kv.Key + ": " + kv.Value ?? "null");

但我建议您阅读并使用Jon Skeet的answer

如果您不想使用反射,则无法遍历对象属性。

您可以在模型中使用一些反射来实现不可数:

public class MyModel : IEnumerable<KeyValuePair<string, object>>
{
    public string Level1_TypeName { get; set; }
    public string Level1_AttrType { get; set; }
    public string Level1_AttrValue { get; set; }
    public string Level2_TypeName { get; set; }
    public string Level2_AttrType { get; set; }
    public string Level2_AttrValue { get; set; }
    public string Level3_TypeName { get; set; }
    public string Level3_AttrType { get; set; }
    public string Level3_AttrValue { get; set; }
    public string Level4_TypeName { get; set; }
    public string Level4_AttrType { get; set; }
    public string Level4_AttrValue { get; set; }
    public string Level5_TypeName { get; set; }
    public string Level5_AttrType { get; set; }
    public string Level5_AttrValue { get; set; }
    public string Level6_TypeName { get; set; }

    public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        return this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToDictionary(p => p.Name, p => p.GetGetMethod().Invoke(this, null)).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

然后您可以像这样使用您的课程:

var obj = new MyModel();
foreach(var kv in obj)
    Console.WriteLine(kv.Key + ": " + kv.Value ?? "null");

答案 2 :(得分:1)

如果你想避免反思,那么你将不得不亲自编写代码。您可以添加一个返回枚举器的方法:

IEnumerable<Tuple<int,string,string,string>> GetLevels()
{
  yield return Tuple.Create(1, Level1_TypeName, Level1_AttrType, Level1_AttrValue);
  yield return Tuple.Create(2, Level2_TypeName, Level2_AttrType, Level2_AttrValue);
  yield return Tuple.Create(3, Level3_TypeName, Level3_AttrType, Level3_AttrValue);
  yield return Tuple.Create(4, Level4_TypeName, Level4_AttrType, Level4_AttrValue);
  yield return Tuple.Create(5, Level5_TypeName, Level5_AttrType, Level5_AttrValue);
  yield return Tuple.Create(6, Level6_TypeName, Level6_AttrType, Level6_AttrValue);
}

现在你可以说:

foreach(var i in myModel.GetLevels())
{
  Console.WriteLine("{0},{1},{2},{3}",i.Item1,i.Item2,i.Item3,i.Item4);
}

答案 3 :(得分:0)

下面的代码不使用反射

using System.ComponentModel;

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(instance);
foreach (PropertyDescriptor prop in props)
{   
}