如何将System.Reflection.PropertyInfo对象转换为其原始对象类型

时间:2016-01-08 05:40:05

标签: c# c#-4.0

寻找将System.Reflection.PropertyInfo转换为原始对象的方法

 public static Child ConvertToChiildObject(this PropertyInfo propertyInfo)
    {
        var p = (Child)propertyInfo;

    }

propertyInfo对象actulayy拥有这样的类

public class Child{
  public string name = "S";
  public string age = "44";

}

到目前为止,我尝试过隐式投射 有没有办法做到这一点?

2 个答案:

答案 0 :(得分:8)

我必须在序言中说这不是问题的答案,而是教育的优点。

正如其他人所解释的那样,你误解了PropertyInfo类的用法。此类用于描述属性,包含与实例相关的数据。因此,如果没有提供一些额外的信息,您无法做到这一点。

现在PropertyInfo可以从对象获取与实例相关的数据,但您必须拥有该对象的实例才能从中读取数据。

例如,采用以下类结构。

public class Child
{
    public string name = "S";
    public string age = "44";
}

public class Parent
{
    public Parent()
    {
        Child = new Child();
    }

    public Child Child { get; set; }
}

属性ChildParent类的属性。构造父类时,将创建一个新的Child实例作为Parent实例的一部分。

然后,我们可以使用Reflection通过简单调用来获取属性Child的值。

var parent = new Parent();
var childProp = typeof(Parent).GetProperty("Child");
var childValue = (Child)childProp.GetValue(parent);

这很好用。重要的部分是(Child)childProp.GetValue(parent)。请注意,我们正在访问GetValue(object)类的PropertyInfo方法,以从Child类的实例中检索Parent属性的值

这很有趣,你必须设计访问属性数据的方法。但是,由于我们已经列出了几次必须拥有该属性的实例。现在我们可以编写一个可以促进此调用的扩展方法。我认为使用扩展方法没有任何优势,因为现有的PropertyInfo.GetValue(object)方法使用起来非常快。但是,如果您想创建父对象的新实例然后获取值,那么可以编写一个非常简单的扩展方法。

public static TPropertyType ConvertToChildObject<TInstanceType, TPropertyType>(this PropertyInfo propertyInfo, TInstanceType instance)
    where TInstanceType : class, new()
{
    if (instance == null)
        instance = Activator.CreateInstance<TInstanceType>();

    //var p = (Child)propertyInfo;
    return (TPropertyType)propertyInfo.GetValue(instance);

}

现在,这种扩展方法只接受一个实例作为第二个参数(或扩展调用中的第一个参数)。

var parent = new Parent();
parent.Child.age = "100";
var childValue = childProp.ConvertToChildObject<Parent, Child>(parent);
var childValueNull = childProp.ConvertToChildObject<Parent, Child>(null);

结果

childValue = name: S, age: 44
childValueNull = name: S, age: 100

请注意拥有实例的重要性。

One Caveat :如果对象为null,则扩展方法将通过调用以下方法创建对象的新实例:

if (instance == null)
    instance = Activator.CreateInstance<TInstanceType>();

您还会注意到typeparam TInstanceType必须是class,并且必须确认new()限制。这意味着它必须是class并且必须具有无参数构造函数。

我知道这不是问题的解决方案,但希望它有所帮助。

答案 1 :(得分:4)

试试这个:

public static Child ConvertToChildObject(this PropertyInfo propertyInfo, object parent)
{
    var source = propertyInfo.GetValue(parent, null);
    var destination = Activator.CreateInstance(propertyInfo.PropertyType);

    foreach (PropertyInfo prop in destination.GetType().GetProperties().ToList())
    {
       var value = source.GetType().GetProperty(prop.Name).GetValue(source, null);
       prop.SetValue(destination, value, null);
    }

    return (Child) destination; 
}

在上文中,我使用了额外参数parent,它是Child的基础对象。