When calling a public method on a private class which takes a ref param and passing a StrongBox the strong box doesn't get updated


<Thanks>David Miller</Thanks>
   class Dummy
        public int m1(int x) { return x; }
        public int m1(ref int x) { x = x+1; return x; }
        Dummy dummy = new Dummy();
        imb = new TestInvokeMemberBinder(mydefBinder, "m1", false, cinfo);
        MSC::System.Runtime.CompilerServices.StrongBox<int> box = new MSC::System.Runtime.CompilerServices.StrongBox<int>(12);
        dyn = Expression.Dynamic(imb, typeof(object), Expression.Constant(dummy), Expression.Constant(box));
        lambda = Expression.Lambda(dyn);
        d = lambda.Compile();
        o = d.DynamicInvoke(null);
        Console.WriteLine("Dynamic2: {0}, box is {1}", o,box.Value);
the overload resolver produces this code:
.Block(System.Int32 $outParam) {
.Block(System.Object $$ret) {
    $$ret = .Block() {
        .If (
            $$arg1 .Is System.Runtime.CompilerServices.StrongBox`1[System.Int32]
        ) {
            $outParam = $$arg1.Value
        } .Else {
            .Call Microsoft.Scripting.Runtime.ScriptingRuntimeHelpers.IncorrectBoxType((System.Object)$$arg1)
        .Call Microsoft.Scripting.Runtime.BinderOps.InvokeMethod(
            .Constant<System.Reflection.MethodInfo>(Int32 m1(Int32 ByRef)),
            .NewArray System.Object[] {
    ((System.Runtime.CompilerServices.StrongBox`1[System.Int32])$$arg1).Value = $outParam;
and the out param is never updated because we don't take the updated value from the object array that we create to invoke via reflection.


dinov wrote Dec 3, 2009 at 10:11 PM

We also have a different return type when invoking via reflection - object for reflected calls, strongly typed for non-reflected calls. That prevents the language from performing their custom boxing when doing a reflected call.

wrote Dec 9, 2009 at 10:18 PM

wrote Feb 21, 2013 at 11:41 PM