繁体   English   中英

当对泛型使用反射时,PropertyInfo List为null

[英]PropertyInfo List is null when using reflection with generics

我正在使用一种方法尝试遍历对象以获取对象的所有属性,其中一些是对象列表。

除了我在初始对象的属性内检查对象的那一部分之外,所有其他方法均有效。 如果找到对象列表,我希望它遍历它们。

烦人的是,我在任何类型的列表上都得到null

我现在在VS中遇到错误,因为pt未实例化,但是会在运行时出现。

下面是我用来尝试捕获正在解析的任何对象/列表的if语句。

我是沿着正确的(回旋处)方式还是这样做还是完全错误?

有问题的代码-if语句空列表:

public static string DeconstructLists<T>(T obj, string body)
        {
            Type type = obj.GetType();
            PropertyInfo[] properties = type.GetProperties();

            foreach (PropertyInfo property in properties)
            {
                if (property.PropertyType == typeof(string) || property.PropertyType == typeof(int) || property.PropertyType == typeof(bool))
                    body += property.Name + " = " + property.GetValue(obj, null) + Environment.NewLine;

                else
                {
                    if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
                    {
                        //null list exception
                        var list = (IEnumerable)property.GetValue(obj, null);
                        foreach (var item in list)
                        {
                            DeconstructLists(item, body);
                        }

                        // stack overflow exception
                        //var props = property.PropertyType.GetGenericArguments()[0];

                        //foreach (var p in props.GetProperties())
                        //{
                        //    DeconstructLists(p, body);
                        //}
                    }
                }
            }
            return body;
        }

发布创建方法:

public ActionResult Create(Company cmp)
        {
            if (ModelState.IsValid)
            {
                db.companys.Add(cmp);
                db.SaveChanges();
                // send email
                SendEmail(cmp);
                return RedirectToAction("Thankyou", "Home", new { form="ASN" });
            }
            return View(cmp);
        }

发送电子邮件的方法:

public static void SendEmail(Company cm)
        {
            string _body = "";
            string _subject = "ASN Form Request";

            _body = DeconstructLists<Company>(cm, _body);

            using (SmtpClient msgClient = new SmtpClient())
            {
                msgClient.EnableSsl = false;
                msgClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                msgClient.UseDefaultCredentials = false;
                msgClient.Credentials = new NetworkCredential
                    {                    
                        UserName = "",
                        Password = ""
                    };
                msgClient.Host = "";
                msgClient.Port = 0;

                using (MailMessage msg = new MailMessage())
                {
                    msg.To.Add(""); // to add
                    msg.From = new MailAddress("");// from add
                    msg.Subject = _subject;
                    msg.Body = _body;
                    // preparing the message to be sent
                    msgClient.Send(msg);
                }
            }
        }

类对象:

public class Company
    {
        public int companyId { get; set; }
        public string name { get; set; }
        public string telephone { get; set; }
        public string regNumber { get; set; }
        public virtual IList<Asn> asns { get; set; }
        public virtual IList<Contact> contacts { get; set; }
    }
    public class Contact
    {
        public int contactId { get; set; }
        public int companyId { get; set; }
        public Company company { get; set; }
        public string name { get; set; }
        public string telephone { get; set; }
    }
public class Asn
    {
        public int asnId { get; set; }
        public int companyId { get; set; }
        public Company company { get; set; }
        public bool userBehalf { get; set; }
        public bool something { get; set; }
    }

如果找到对象列表,我希望它遍历它们。

您不需要迭代list ,最小可迭代类型为IEnumerable 实际上,您的if语句正在检查

if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
    // ...
}

那为什么不只是在内部使用

var list = (IEnumerable)property.GetValue(obj, null);
foreach (var item in list)
{
    DeconstructLists(item, body);
}

编辑:看到它,它工作,然后看看为什么你的不:

using System;
using System.Collections;
using System.Collections.Generic;

namespace Tests
{
    class Test
    {
        static void Main(string[] args)
        {
            var company = new Company
            {
                companyId = 1,
                name = "ACME",
            };
            company.asns = new List<Asn>
            {
                new Asn { asnId = 1, companyId = company.companyId, company = company  },
                new Asn { asnId = 2, companyId = company.companyId, company = company  },
            };
            company.contacts = new List<Contact>
            {
                new Contact { contactId = 1, companyId = company.companyId, company = company, name = "Contact1" },
                new Contact { contactId = 2, companyId = company.companyId, company = company, name = "Contact2" }
            };
            var body = DeconstructLists(company, "");
        }
        public static string DeconstructLists<T>(T obj, string body)
        {
            var type = obj.GetType();
            var properties = type.GetProperties();
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(string) || property.PropertyType == typeof(int) || property.PropertyType == typeof(bool))
                    body += property.Name + " = " + property.GetValue(obj, null) + Environment.NewLine;
                else
                {
                    if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
                    {
                        body = body + property.Name + ": {" + Environment.NewLine;
                        var list = (IEnumerable)property.GetValue(obj, null);
                        foreach (var item in list)
                        {
                            body = body + item.GetType().Name + ": {" + DeconstructLists(item, "") + "}" + Environment.NewLine;
                        }
                        body = body + "}" + Environment.NewLine;
                    }
                }
            }
            return body;
        }
    }
    public class Company
    {
        public int companyId { get; set; }
        public string name { get; set; }
        public string telephone { get; set; }
        public string regNumber { get; set; }
        public virtual IList<Asn> asns { get; set; }
        public virtual IList<Contact> contacts { get; set; }
    }
    public class Contact
    {
        public int contactId { get; set; }
        public int companyId { get; set; }
        public Company company { get; set; }
        public string name { get; set; }
        public string telephone { get; set; }
    }
    public class Asn
    {
        public int asnId { get; set; }
        public int companyId { get; set; }
        public Company company { get; set; }
        public bool userBehalf { get; set; }
        public bool something { get; set; }
    }
}

也许您可以在if语句中尝试类似的方法?

var genericType = property.PropertyType.GetGenericArguments()[0];
foreach (var prop in genericType.GetProperties())
{
    DeconstructLists(prop, body);
}

本主题还可以为您提供帮助: 如何从泛型类或方法的成员中获取T的类型?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM