Kalanamith
Kalanamith

Reputation: 20668

How to convert System.Reflection.PropertyInfo object to its original object type

Um looking for a way to convert a System.Reflection.PropertyInfo to its original object

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

    }

The propertyInfo object actulayy holds a class like this

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

}

So far I have tried implicit casting Is there a way to do this?

Upvotes: 13

Views: 16983

Answers (2)

Madhu
Madhu

Reputation: 2551

Try this:

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; 
}

In the above, I used the extra parameter parent which is the base object of the Child.

Upvotes: 7

Nico
Nico

Reputation: 12683

I must preface that this is not an answer to the question but an education excersise.

As others have explained you are misunderstanding the usage of the PropertyInfo class. This class is used to describe the property and does not contain and instance related data. Therefore what you are trying to do is not possible without some additional information provided.

Now the PropertyInfo class can get the instance related data from an object but you must have an instance of the object to read the data from.

For example, take the following class structure.

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

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

    public Child Child { get; set; }
}

The property Child is a property of the Parent class. When the parent class is constructed a new Child instance is created as part of the Parent instance.

We can then use Reflection to get the value of the property Child by simply calling.

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

This works just fine. The important part is (Child)childProp.GetValue(parent). Note that we are accessing the GetValue(object) method of the PropertyInfo class to retrieve the value of the Child property from the instance of the Parent class.

This is fundementally how you would have to design the method for accessing the property data. However as we have listed a few times you must have an instance of the property. Now we can write an extension method that will faciliate this call. As I see it there is no advantage to use an extension method as the existing PropertyInfo.GetValue(object) method is quite quick to use. However if you would like to create a new instance of the parent object then get the value then you could write a very simply extension method.

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);

}

Now this extension method simply accepts an instance as a second parameter (or first in the extension call).

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

Results

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

Note the importance of having an instance.

One Caveat: The extension method will create a new instance of the object if the object is null by calling:

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

You will also notice the typeparam TInstanceType must be a class and must confirm to the new() restriction. This means it must be a class and must have a parameterless constructor.

I understand this isn't a solution to the question, but hope it helps.

Upvotes: 16

Related Questions