我不确定该标题是否反映了实际问题,所以让我解释一下。有没有办法实例化一个类并递归实例化所有类的属性?
例如:
public class Base
{
public int BaseValue{ get; set;}
}
public class Extended : Base
{
public int ExtendedValue{ get; set;}
public AnotherExtendedClass AnotherClass { get; set;}
}
我想创建一个由Extended
的空实例组成的json有效负载,其中所有默认值和属性都已实例化。并使用它:
string representation = Test.CreateDefaultEmptyJson(Extended);
public static string CreateDefaultEmptyJson(Type type)
{
JsonSerializerSettings settings = new JsonSerializerSettings().Configure();
var defaultInstance= Activator.CreateInstance(type);
return JsonConvert.SerializeObject(defaultInstance, settings);
}
输出不包含Extended
类属性。我回来了:
{
"BaseValue":0
}
当我真的想看(或类似的东西)时:
{
"BaseValue":0,
{
"ExtendedValue":0,
{
...
}
}
}
我想我可以递归迭代所有类型的Extended
并调用默认构造函数,但是,在我走这条路之前,可能会有几行代码来完成相同的工作。
答案 0 :(得分:1)
这个匆匆写的课程开始解决你的问题。它返回可返回引用类型的可设置属性,并以递归方式遍历它们,根据需要创建实例。
它不包括
您可能最好只在属性本身上设置默认值,以便不会使用不需要的空值创建类。
public class PropertyPopulator
{
public void PopulateProperties(object target)
{
var properties = target.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.PropertyType.IsClass && p.CanWrite && p.CanRead);
foreach (var property in properties)
{
var propertyValue = property.GetValue(target);
if (propertyValue == null)
{
var constructor = property.PropertyType.GetConstructor(new Type[] { });
if (constructor != null)
{
propertyValue = constructor.Invoke(new object[] { });
property.SetValue(target, propertyValue);
PopulateProperties(propertyValue);
}
}
}
}
}
答案 1 :(得分:1)
据我所知,除了编写自己的递归方法之外,没有一种内置的方法。
但是,假设:
然后你可以用大约十几行代码创建这样一个方法:
public static string CreateDefaultEmptyJson(Type type)
{
return JsonConvert.SerializeObject(RecursiveCreateInstance(type), Formatting.Indented);
}
public static object RecursiveCreateInstance(Type type)
{
object obj = null;
ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
if (ctor != null)
{
obj = ctor.Invoke(null);
foreach (PropertyInfo prop in type.GetProperties())
{
Type propType = prop.PropertyType;
if (prop.CanWrite && propType.IsClass)
{
prop.SetValue(obj, RecursiveCreateInstance(propType));
}
}
}
return obj;
}
小提琴:https://dotnetfiddle.net/3VMTsC
如果上述假设不成立,那么事情就会变得复杂起来。如果您遇到需要轻松创建虚假对象以进行测试的问题,那么您可能需要考虑使用mocking framework。