我正在使用一种方法来尝试迭代一个对象来获取所有对象的属性,其中一些是对象列表。
除了检查初始对象属性中的对象的部分外,这一切都有效。如果它找到了一个对象列表,我希望它迭代它们。
令人讨厌的是,我在{+ 1}}列表中列出了任何类型的内容。
我现在在VS中收到错误,因为null
没有实例化,但它会在运行时。
下面是我用来尝试捕获正在解析的任何对象/列表的if语句。
我是走右路(环形交叉路口)还是做这个还是完全错了?
有问题的代码 - 如果语句空列表:
pt
发布创建方法:
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);
}
}
}
答案 0 :(得分:3)
如果它找到了一个对象列表,我希望它迭代它们。
迭代时不需要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; }
}
}
答案 1 :(得分:1)
也许你可以在if语句中尝试这样的事情吗?
var genericType = property.PropertyType.GetGenericArguments()[0];
foreach (var prop in genericType.GetProperties())
{
DeconstructLists(prop, body);
}
此主题也可以为您提供帮助:How to get the type of T from a member of a generic class or method?