使用反射从复杂类中获取值 [英] Get Values From Complex Class Using Reflection

查看:37
本文介绍了使用反射从复杂类中获取值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它是从一个 xml 字符串创建和填充的,为了示例目的,我已经简化了它:

I have a class, which is created and populated from an xml string, I've simplified it for example purposes:

[XmlRoot("Person")]
public sealed class Person
{
    [XmlElement("Name")]
    public string Name { get; set; }

    [XmlElement("Location")]
    public string Location { get; set; }

    [XmlElement("Emails", Type = typeof(PersonEmails)]
    public PersonEmails Emails { get; set; }
}

public class PersonEmails
{
    [XmlElement("Email", Type = typeof(PersonEmail))]
    public PersonEmail[] Emails { get; set; }
}

public class PersonEmail
{
    [XmlAttribute("Type")]
    public string Type { get; set; }

    [XmlText]
    public string Value { get; set; }
}

为了提取信息,我试图将它们加载到另一个类中,这很简单:

To extract the information, I'm trying to load them into another class, which is simply:

public class TransferObject
{
    public string Name { get; set; }

    public ObjectField[] Fields { get; set; }
}

public class ObjectField
{
    public string Name { get; set; }
    public string Value { get; set; }
}

我只是从另一个对象填充字段",它只是 (Name = "Location", Value = "London"),但对于电子邮件,(Name = "Email"+Type, Value = jeff@here.com)

I'm only populating "Fields" from the other object, which would simply be (Name = "Location", Value = "London"), but for Emails, (Name = "Email"+Type, Value = jeff@here.com)

目前我可以填充所有其他字段,但我被电子邮件困住了,并且知道如何深入挖掘以能够使用反射(或不使用)来获取我需要的信息.目前我正在使用:

Currently I can populate all the other fields, but I'm stuck with Emails, and knowing how to dig deep enough to be able to use reflection (or not) to get the information I need. Currently I'm using:

Person person = Person.FromXmlString(xmlString);
List<ObjectField> fields = new List<ObjectField>();
foreach (PropertyInfo pinfo in person.getType().GetProperties()
{
    fields.Add(new ObjectField { Name = pinfo.Name, Value = pinfo.getValue(person, null).ToString();
}

如何扩展上述内容以将我的所有电子邮件添加到列表中?

How can I expand on the above to add all my emails to the list?

推荐答案

您试图将复杂值类型转换为字符串值,因此丢失了数据.而是使用以下代码:

You are trying to type cast a complex values type to string value so you lost the data. Instead use following code:

class Program
{
    static void Main(string[] args)
    {
        Person person = new Person();
        person.Name = "Person One";
        person.Location = "India";
        person.Emails = new PersonEmails();
        person.Phones = new PersonPhones();
        person.Emails.Emails = new PersonEmail[] { new PersonEmail() { Type = "Official", Value = "xyz@official.com" }, new PersonEmail() { Type = "Personal", Value = "xyz@personal.com" } };
        person.Phones.Phones = new PersonPhone[] { new PersonPhone() { Type = "Official", Value = "789-456-1230" }, new PersonPhone() { Type = "Personal", Value = "123-456-7890" } };

        List<ObjectField> fields = new List<ObjectField>();

        fields = GetPropertyValues(person);

    }

    static List<ObjectField> GetPropertyValues(object obj)
    {
        List<ObjectField> propList = new List<ObjectField>();

        foreach (PropertyInfo pinfo in obj.GetType().GetProperties())
        {
            var value = pinfo.GetValue(obj, null);

            if (pinfo.PropertyType.IsArray)
            {
                var arr = value as object[];
                for (var i = 0; i < arr.Length; i++)
                {
                    if (arr[i].GetType().IsPrimitive)
                    {
                        propList.Add(new ObjectField() { Name = pinfo.Name + i.ToString(), Value = arr[i].ToString() });
                    }
                    else
                    {
                        var lst = GetPropertyValues(arr[i]);
                        if (lst != null && lst.Count > 0)
                            propList.AddRange(lst);
                    }
                }
            }
            else
            {
                if (pinfo.PropertyType.IsPrimitive || value.GetType() == typeof(string))
                {
                    propList.Add(new ObjectField() { Name = pinfo.Name, Value = value.ToString() });
                }
                else
                {
                    var lst = GetPropertyValues(value);
                    if (lst != null && lst.Count > 0)
                        propList.AddRange(lst);
                }
            }
        }
        return propList;
    }
}

这篇关于使用反射从复杂类中获取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆