Francis Ducharme
Francis Ducharme

Reputation: 4987

Casting through reflection from simple type to complex type

I'm looking into casting, in this case, from Int32 to a more complex type.

Here's how you would get an instance of this complex type through normal means:

OptionSetValue option = new OptionSetValue(90001111); //int value...

Now, I am trying to do this via reflection. Here is my method doing it:

    public static void SetValue(object entity, string propertyName, object value)
    {
        try
        {
            PropertyInfo pi = entity.GetType().GetProperty(propertyName);
            Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;
            object safeValue = (value == null) ? null : Convert.ChangeType(value, t); //Line where the exception is thrown...
            pi.SetValue(entity, safeValue, null);

        }
        catch
        {
            throw;
        }

        return;
    }

And here's how I use it:

SetValue(entity, "reason", 90001111);

"reason" is a property of entity of type OptionSetValue. When using it like this, on the above noted line, I will get this exception:

Invalid cast from 'System.Int32' to 'Microsoft.Xrm.Sdk.OptionSetValue'.

Is it because the two properties come from different assemblies ? If so, it is even possible to do what I am after ?

Thanks,

Upvotes: 1

Views: 853

Answers (2)

neontapir
neontapir

Reputation: 4736

I think you answered your own question.

"reason" is a property of entity of type OptionSetValue

If that's the case, then pi.PropertyType is OptionSetValue, and

Type t = Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType;

returns OptionSetValue.

The invalid cast comes from Convert.ChangeType(value, t). Since a converter for OptionSetValue hasn't been registered, the runtime doesn't know how to do this conversion. Also see this MSDN article on how to register a TypeConverter if you are interested in going that route.

See Eve's use of Activator.CreateInstance to see how to overcome this issue.

Upvotes: 2

e_ne
e_ne

Reputation: 8459

You can't cast an integer to that class. Use the following code instead:

object safeValue = (value == null) ? null : Activator.CreateInstance(t, value);

What the above code does is creating a new instance of OptionSetValue and passing your value to its constructor.

Upvotes: 1

Related Questions