我想以递归方式构建一个复杂的对象。
public class Name
{
public string firstName {get;set;}
public string lastName {get;set;}
}
public class Address
{
public string city {get;set;}
public string state {get;set;}
public string street {get;set;}
public string zip {get;set;}
}
public class Customer
{
public Name customerName {get;set;}
public Address customerAddress {get;set;}
public Guid id {get;set;}
}
让我们说客户住在我正在装载的装配中:) 我想实例化一种Customer并填充其属性。 Customer对象具有更多自定义对象和Guid属性。如何使用递归来创建Customer对象及其嵌套对象。我在下面有一些代码,我偶然发现我应该使用递归。
static object TraversePropertyInfo(object obj, Assembly assembly)
{
Console.WriteLine(obj.GetType().Name);
foreach(PropertyInfo pi in obj.GetType().GetProperties())
{
if(pi.PropertyType.IsClass && pi.PropertyType.Namespace != "System")
{
if(pi.PropertyType.UnderlyingSystemType.GenericTypeArguments.Count() > 0)
{
Console.WriteLine("\tIList<{0}>", pi.Name);
}
else
{
Console.WriteLine("\t{0}\t<class>", pi.Name);
object child = Activator.CreateInstance(assembly.GetType(pi.PropertyType.FullName)); // create the child instance
obj.GetType().GetProperty(pi.Name).SetValue(obj, child); // set the child on the parent
// but the child can have children...
// I should be using recurrsion here
}
}
else
{
Console.WriteLine("\t{0}\t{1}", pi.Name, pi.PropertyType);
}
}
return obj;
}
答案 0 :(得分:5)
void Main()
{
Create<Customer>().Dump();
}
// Define other methods and classes here
public class Name
{
public string Firstname { get; set; }
public string Lastname { get; set; }
}
public class Address
{
public string City { get; set; }
public string State { get; set; }
public string Street { get; set; }
public string Zip { get; set; }
}
public class Customer
{
public Name CustomerName { get; set; }
public Address CustomerAddress { get; set; }
public Guid Id { get; set; }
}
public static T Create<T>()
{
var type = typeof(T);
return (T)Create(type);
}
public static object Create(Type type)
{
var obj = Activator.CreateInstance(type);
foreach(var property in type.GetProperties())
{
var propertyType = property.PropertyType;
if (propertyType.IsClass
&& string.IsNullOrEmpty(propertyType.Namespace)
|| (!propertyType.Namespace.Equals("System")
&& !propertyType.Namespace.StartsWith("System.")))
{
var child = Create(propertyType);
property.SetValue(obj, child);
}
}
return obj;
}
答案 1 :(得分:0)
也许这会奏效:
static object TraversePropertyInfo(object obj, Assembly assembly)
{
Console.WriteLine(obj.GetType().Name);
// we stop the iteration when we reached the root-class "object"
// which won´t add any custom properties
if (obj.GetType() == typeof(object) return obj;
foreach(PropertyInfo pi in obj.GetType().GetProperties())
{
if(pi.PropertyType.IsClass && pi.PropertyType.Namespace != "System")
{
if(pi.PropertyType.UnderlyingSystemType.GenericTypeArguments.Count() > 0)
{
Console.WriteLine("\tIList<{0}>", pi.Name);
}
else
{
Console.WriteLine("\t{0}\t<class>", pi.Name);
object child = Activator.CreateInstance(assembly.GetType(pi.PropertyType.FullName)); // create the child instance
child = TraversePropertyInfo(child, child.GetType().Assembly);
obj.GetType().GetProperty(pi.Name).SetValue(obj, child); // set the child on the parent
// this will do the recursion
return obj;
}
}
else
{
Console.WriteLine("\t{0}\t{1}", pi.Name, pi.PropertyType);
}
}
return obj;
}