在运行时创建属性的未知类类型的实例
本文关键字:类型 实例 未知 创建 属性 运行时 | 更新日期: 2023-09-27 18:31:17
我需要检测属性的类型何时是类类型及其构造函数参数(如果有)。类会有所不同,并且不能硬编码。我有一个如下所示的属性类型,并且使用反射,我根据确定的类型以不同的方式处理属性。
public class SomeClass
{
// Process this one and instantiate its class type
public WhateverClass Whatever
{
get;
set;
}
// This one will be skipped since its not a user defined class type
public string SomePropName
{
get;
set;
}
}
现在,当我反映类中的属性时(例如 SomeClass)。我需要对属性类型做一些不同的事情,但有些类型是类,它们在构造函数中可能有也可能不需要参数,但由于它在运行时全部确定,我必须动态反映构造函数。
if (propertyInfo.PropertyType.IsClass)
{
var propType = propertyInfo.PropertyType.UnderlyingSystemType;
// Something like this
var ctx = propType.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, null, null);
// todo: instanciate new class instance
}
现在有没有更好的方法来剥这只猫的皮,如果没有,当我不知道构造函数参数时,我该如何创建类?
谢谢
如果你需要知道一个对象的任何/所有构造函数,有一个" GetConstructors
"方法返回该类的构造函数数组:
propType.GetConstructors();
前任:
类
public class PropertyClass
{
public PropertyClass()
{
Value = "default";
}
public PropertyClass(string value)
{
Value = value;
}
public string Value { get; private set; }
}
public class WhateverClass
{
public PropertyClass Property { get; set; }
}
。
用法
var propertyInstances = GeneratePropertyForEachConstructor(typeof(WhateverClass), "Property").Cast<PropertyClass>();
foreach (PropertyClass propertyInstance in propertyInstances)
{
Console.WriteLine("value: {0}", propertyInstance.Value);
}
。
方法:
public List<object> GeneratePropertyForEachConstructor(Type type, string propertyName)
{
var propertyInfo = type.GetProperty(propertyName);
return GeneratePropertyForEachConstructor(type, propertyInfo);
}
public List<object> GeneratePropertyForEachConstructor(Type type, PropertyInfo propertyInfo)
{
List<object> results = new List<object>();
if (propertyInfo.PropertyType.IsClass)
{
var propType = propertyInfo.PropertyType.UnderlyingSystemType;
var constructors = propType.GetConstructors();
foreach (ConstructorInfo constructorInfo in constructors)
{
var parameterInfo = constructorInfo.GetParameters();
var constructorParams = new List<object>();
foreach (ParameterInfo constructorParam in parameterInfo)
{
object value = constructorParam.HasDefaultValue
? constructorParam.DefaultValue
: constructorParam.ParameterType.IsValueType
? Activator.CreateInstance(constructorParam.ParameterType)
: null;
constructorParams.Add(value);
}
results.Add(constructorInfo.Invoke(constructorParams.ToArray()));
}
}
return results;
}
输出
值:默认值
价值:
在这种情况下,我们可以看到它遍历了两个构造函数,并为具有 String 参数的构造函数传入了 String 的默认值。