+4  A: 

You will have to do the conversion yourself, as the compiler handles the cast in a non-reflection environment. As reflection code basically is evaluating types and objects like the compiler does, you will have to look for a method named op_implicit with the needed parameters (in your case Int32) on your object and invoke it. After that, you can invoke the property accessor. A possible way would be the following:

//search for an implicit cast operator on the target type
MethodInfo[] methods = targetType.GetMethods();
foreach(MethodInfo method = source.GetType().GetMethod("op_Implicit"))
{
  if (method.Name == "op_Implicit")
  {
    ParameterInfo[] parameters = method.GetParameters();
    if (parameters.Length == 1 && parameters[0].ParameterType == value.GetType())
    {
      value = method.Invoke(obj,new object[]{value});
      break;
    }
  }
}
Femaref
This is essentially what worked for me. At least it got me on the right track. Thanks!
Mike
`MethodInfo method = source.GetType().GetMethod("op_Implicit");` is easier to read than the explicitly looped search.
Merlyn Morgan-Graham
@Merlyn, yeah, you'll notice that's what I did if you read my first edit, except I also added the type into the GetMethod() call as well. Otherwise if there were multiple overloaded op_Implicit methods, I think I'd still have to loop?
Mike
@Mike: Oops - you're right. I guess your other option would be to use LINQ, if you prefer it.
Merlyn Morgan-Graham
+2  A: 

Why would an implicit type conversion that works fine elsewhere fail with reflection?

Because there is no conversion there. Implicit conversion doesn't mean that it happens automatically, when you use it in code the compiler adds the code for it.

If you want to use it in reflection, you have to do the same, i.e. find the static method that does the conversion from one type to the other, and call it.

Guffa
Thanks for the explanation. I guess I was hoping that reflection would have an easier way to do that, but alas.
Mike
+5  A: 

The runtime doesn't know about implicit conversions.

You can call op_Implicit or another conversion method through reflection, but that way you'll only get the specific conversion semantics that you implement. If you're using C# 4.0, I'd recommend using the "dynamic" type here, since it will implement the C# conversion semantics automatically.

Jesse McGrew
+1 for C# 4.0 `dynamic` recommendation
Merlyn Morgan-Graham
Thanks for this. We are using C# 3.5, but I keep seeing C# 4.0 features like this that look handy.
Mike
+1  A: 

Other answers have already covered why the implicit conversion isn't working. If you need your conversion to be implicit, then use one of the other answers. In case you don't actually need the conversion to be implicit, here is a simpler option:

class Test
{
  public decimal? Val { get; set; }
}

class Program
{
  static void Main(string[] args)
  {
    object o = new Test();
    object source = 5;
    var setMethod = typeof(Test).GetProperty("Val").GetSetMethod();
    // Just do the cast explicitly
    setMethod.Invoke(o, new object[] { (decimal?)(int)source });
  }
}

Note that if you're missing the (decimal?) cast, you get the error that the original question quoted. If you're missing the (int) cast, you get this error:

Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
   at Program.Main(String[] args) in ...\ConsoleApplication1\Program.cs:line 14
Merlyn Morgan-Graham
Novel idea; it made me chuckle at least. I guess I should have said this in the question, but the real objective was to make this dynamic; I am not always doing (decimal?)(int). =)
Mike
@Mike: I figured as much, but you can't gauge experience w/ a single question over the internet. It wouldn't be 100% obvious to a newbie that you have to cast *twice* to get this to work. I will leave this answer, in case it is useful to someone less skilled, who still encounters the same error.
Merlyn Morgan-Graham