user3174976
user3174976

Reputation: 351

In Reflection, how to set a correct value for a property?

My target is to find all the "string" type properties, and assign them to a specific string value, like "This is a testing string".

I can find all the string type properties in a class now, but always have problems when assigning string value to the property in a class, which is the class property of another class.

 public class Credit_Card
{
    public string brand { get; set; }
    public int billing_phone { get; set; }
    public string credit_card_verification_number { get; set; }
    public Expiration expiration { get; set; }
}

public class Expiration
{
    public string month { get; set; }
    public string year { get; set; }
}

 class Program
{
    static void Main(string[] args)
    {
        Credit_Card credcard = new Credit_Card { brand = "Visa", billing_phone = 12345, credit_card_verification_number = "1234", expiration = new Expiration { month = "11", year = "2016" } };
        foreach (PropertyInfo prop in GetStringProperties(credcard.GetType()))
        {
            prop.SetValue(credcard,"testing string!!",null);
            Console.WriteLine(prop.GetValue(credcard,null));
        }
        Console.ReadLine();
    }

    public static IEnumerable<PropertyInfo> GetStringProperties(Type type)
    {
        return GetStringProperties(type, new HashSet<Type>());
    }

    public static IEnumerable<PropertyInfo> GetStringProperties(Type type, HashSet<Type> alreadySeen)
    {
        foreach (var prop in type.GetProperties())
        {
            var propType = prop.PropertyType;
            if (propType == typeof(string))
                yield return prop;
            else if (alreadySeen.Add(propType))
                foreach (var indirectProp in GetStringProperties(propType, alreadySeen))
                    yield return indirectProp;
        }
    }
}

It always throws the exception when the loop runs to "month" property of Expiration class.

How can I assign the correct value into the correct instance?

Upvotes: 0

Views: 58

Answers (2)

TyCobb
TyCobb

Reputation: 9089

Looking at the code, you are grabbing all string properties on Credit_Card then recursively grabbing all string properties on child objects.

Your problem is coming from the fact that it is returning string month from Expiration. You then are attempting to set the Expiration.month property on your Credit_Card instance credcard.

That does not work. The target must match the same Type that declared the PropertyInfo. This is why you are getting:

System.Reflection.TargetException was unhandled, and the messagei is "Object does not match target type"

You need to split your loop up so you do them in correct hierarchy chain and have the correct instance (target) that will be updated with your data.

Upvotes: 0

user4426213
user4426213

Reputation:

If you wanted to assign month and year values you would need to get their PropInfo by doing Type.GetType(CredCard.Expiration).Properties because they aren't properties of credcard but are properties of credcard.Expiration.

You would have to check for the properties and assign them to credcard.Expiration rather than credcard.

// prop.Name == "month" || prop.Name == "year"
prop.SetValue(credcard.Expiration, "somestring");

Another alternative would be to assign a new Expiration object to the Expiration property:

if(prop.Name.Equals("Expiration"))
{
  var expiration = new Expiration
  {
   month = "someString",
   year = "someString"
  };
  prop.SetValue(credcard,expiration);
}

Upvotes: 1

Related Questions