C# 实例化包含所有对象属性的类型实例,并遵守继承
我不确定这个标题是否反映了实际问题,所以让我解释一下。有没有一种方法可以实例化一个类并递归实例化所有属于类的属性 例如:C# 实例化包含所有对象属性的类型实例,并遵守继承,c#,reflection,json.net,C#,Reflection,Json.net,我不确定这个标题是否反映了实际问题,所以让我解释一下。有没有一种方法可以实例化一个类并递归实例化所有属于类的属性 例如: public class Base { public int BaseValue{ get; set;} } public class Extended : Base { public int ExtendedValue{ get; set;} public AnotherExtendedClass AnotherClass { get; set;
public class Base
{
public int BaseValue{ get; set;}
}
public class Extended : Base
{
public int ExtendedValue{ get; set;}
public AnotherExtendedClass AnotherClass { get; set;}
}
我想创建一个json负载,它由一个Extended
的空实例组成,并实例化所有默认值和属性。然后像这样使用它:
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);
}
输出不包括扩展的
类属性。我回来了:
{
"BaseValue":0
}
当我真的想看(或类似的东西)的时候:
我想我可以递归地迭代所有类型的
Extended
,并调用默认构造函数,然而,在我继续这条路之前,可能会有几行代码来完成相同的任务。这个匆忙编写的类开始解决您的问题。它返回可设置的属性,这些属性返回引用类型并递归遍历它们,根据需要创建实例
它不包括
- 索引属性
- 递归深度
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);
}
}
}
}
}
这节仓促编写的课开始解决你的问题。它返回可设置的属性,这些属性返回引用类型并递归遍历它们,根据需要创建实例 它不包括
- 索引属性
- 递归深度
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);
}
}
}
}
}
据我所知,除了编写自己的递归方法之外,没有一种内置的方法来实现这一点。
但是,假设:
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;
}
小提琴:
如果上述假设不成立,那么事情很快就会变得复杂。如果您遇到了一些问题,需要一种简单的方法来创建假对象以进行测试,那么您可能需要考虑使用。据我所知,除了编写自己的递归方法之外,没有一种内置的方法来实现这一点。
但是,假设:
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;
}
小提琴:
如果上述假设不成立,那么事情很快就会变得复杂。如果您遇到一些问题,需要一种简单的方法来创建用于测试目的的假对象,那么您可能需要考虑使用。我的回答也忽略了问题的一个要求。您希望实例化一个对象,而不是从一个实例开始并根据需要填充属性。但在这种情况下,我仍然倾向于设置属性的默认值,以便它们一开始不为null。然后你只需要创建一个基类型的新实例,其余的就可以了。您希望实例化一个对象,而不是从一个实例开始并根据需要填充属性。但在这种情况下,我仍然倾向于设置属性的默认值,以便它们一开始不为null。然后,您只需创建一个基类型的新实例,其余的将自行处理。