在运行时创建属性的未知类类型的实例

时间:2014-11-19 21:48:55

标签: c# reflection

我需要检测属性的类型何时是类类型及其构造函数参数(如果有)。这些类会有所不同,不能进行硬编码。我有一个类似下面的属性类型并使用反射我根据确定的类型不同地处理属性。

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

}

现在是否有更好的方法来修饰这只猫,如果没有,当我不知道构造函数参数时如何创建类?

由于

1 个答案:

答案 0 :(得分:0)

如果你需要知道一个对象的任何/所有构造函数,那么有一个“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;
} 

<强>输出

  

值:默认

     

值:

在这种情况下,我们可以看到它循环遍历两个构造函数,并为具有字符串参数的构造函数传递了字符串的默认值。