C#和反射的使用

C#和反射的使用,c#,reflection,iteration,C#,Reflection,Iteration,我访问了这个站点(),它演示了反射的使用,如下所示: public class Person { public int Age { get; set; } public string Name { get; set; } } private void button2_Click_1(object sender, EventArgs e) { var person = new Person { Age = 30, Na

我访问了这个站点(),它演示了反射的使用,如下所示:

public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
    }

   private void button2_Click_1(object sender, EventArgs e)
    {
        var person = new Person { Age = 30, Name = "Tony Montana" };
        var properties = typeof(Person).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(person, null));
        }
    }
上面的代码片段将为您提供: 年龄:30 姓名:托尼·蒙大拿

如果我们像这样在“另一个人”的课堂上加上“孩子”怎么办

    public class Kid
    {
        public int KidAge { get; set; }
        public string KidName { get; set; }
    }
    public class AnotherPerson
    {
        public int Age { get; set; }
        public string Name { get; set; }
        public Kid Kid { get; set; }
    }
这个片段

private void button3_Click(object sender, EventArgs e)
    {
        var anotherPerson = new AnotherPerson { Age = 30, Name = "Tony Montana", Kid = new Kid { KidAge = 10, KidName = "SomeName" } };
        var properties = typeof(AnotherPerson).GetProperties();
        foreach (PropertyInfo property in properties)
        {
            Console.WriteLine("{0} = {1}", property.Name, property.GetValue(anotherPerson, null));
        }
    }
给我: 年龄:30 姓名:托尼·蒙大拿 Kid:ProjectName.Form1+Kid


不完全是我想要的。。。。我可以使用反射来迭代“Kid”吗?建议?

可以有这样的帮助方法吗

public List<KeyValuePair<string, object>> GetPropertiesRecursive(object instance)
{
  List<KeyValuePair<string, object>> propValues = new List<KeyValuePair<string, object>>();
  foreach(PropertyInfo prop in instance.GetType().GetProperties())
  {
    propValues.Add(new KeyValuePair<string, object>(prop.Name, prop.GetValue(instance, null));
    propValues.AddRange(GetPropertiesRecursive(prop.GetValue(instance));
  }
}
public List GetPropertiesRecursive(对象实例)
{
List propValues=新列表();
foreach(实例.GetType().GetProperties()中的PropertyInfo属性)
{
Add(新的KeyValuePair(prop.Name,prop.GetValue(instance,null));
AddRange(GetPropertiesRecursive(prop.GetValue(实例));
}
}

调用as-
GetPropertiesRecursive(另一个人)

代码在属性中循环,并使用
ToString
(通过
Console.WriteLine
使用的
String.Format
方法)获取属性值的字符串表示形式

如果要更改
Kid
属性值的显示方式,基本上有两个选项:

  • 检查反射代码中属性的类型(
    property.PropertyType
    ),以便可以对
    Kid
    类型执行不同的操作

  • 重写
    Kid
    类中的
    ToString
    方法,以便它返回您希望显示为值的任何字符串


  • 执行递归的方法可以获取属性中属性的值:

    public static string GetProperties(object obj)
    {
        var t = obj.GetType();
        var properties = t.GetProperties();
        var s = "";
        foreach (PropertyInfo property in properties)
        {
            object propValue = property.GetValue(obj, new object[0]);
            string propertyToString;
            if (t.GetMethod("ToString").DeclaringType != typeof(object))
                propertyToString = propValue.ToString();
            else if (typeof(IConvertible).IsAssignableFrom(property.PropertyType))
                propertyToString = Convert.ToString(propValue);
            else
                propertyToString = GetProperties(propValue);
    
            s += string.Format("'{0}' = '{1}'", property.Name, propertyToString);
        }
        return s;
    }
    

    如果您考虑到实际用途,JSON(或其他)序列化可能更合适,例如,使用将生成类似的字符串。

    kid
    object执行同样的操作您是否真的对某种形式的序列化感兴趣,如JSON?您需要递归调用输出方法,查看某个属性是否为对象我相信这个问题就解决了:您不需要<代码>类型parameter@I4V我正要改变这一点;)如果OP在另一个人的
    中添加了
    青少年
    类型,会发生什么情况呢?在这种情况下,反射的想法可能是为了让它在将来尽可能通用:)这太不灵活了。是的,要使它灵活,您应该处理基本类型、数组、列表、字典和索引属性。即使如此,它与类本身的耦合也太紧密了。一个好的灵活的解决方案将检查属性本身是否为类或值类型,并以这种方式处理它。@James,但这不仅仅是类型是否为值类型;这是一个类型是否以提供所需信息的方式覆盖
    ToString
    的问题。有很多自定义值类型不能做到这一点,还有很多自定义类可以做到这一点。
    public static string GetProperties(object obj)
    {
        var t = obj.GetType();
        var properties = t.GetProperties();
        var s = "";
        foreach (PropertyInfo property in properties)
        {
            object propValue = property.GetValue(obj, new object[0]);
            string propertyToString;
            if (t.GetMethod("ToString").DeclaringType != typeof(object))
                propertyToString = propValue.ToString();
            else if (typeof(IConvertible).IsAssignableFrom(property.PropertyType))
                propertyToString = Convert.ToString(propValue);
            else
                propertyToString = GetProperties(propValue);
    
            s += string.Format("'{0}' = '{1}'", property.Name, propertyToString);
        }
        return s;
    }