A problem with porting 1.1 to 2.0

U

Udi

Hi All,
I have a function that I need to call on reflection that has an out
parameter
(maybe more than one).
My problem is that I'm not receiving the out values.

The following code works fine on VS2003, but not on 2005:

ArrayList myArgs = new ArrayList();
Int outVal;
myArgs.Add( outVal );
obj.GetType().InvokeMember( "GetValue",
BindingFlags.SetProperty | BindingFlags.Public |
BindingFlags.Instance,
null,
obj,
(Object [])myArgs.ToArray(typeof(Object)) // FAILS ON 2005
value always returns 0
);


However, this fixes the problem:

object [] myArgs = {new int() };
obj.GetType().InvokeMember( "Memory",
BindingFlags.SetProperty | BindingFlags.Public |
BindingFlags.Instance,
null,
obj,
myArgs) // WORKS FINE
);

I guess this is related to a temporary array that is returned from
'ToArray()' and gets lost,
but I still don't really understand what's happening there.
Can anyone please explain to me what's exactly happening behind the
scenes, or point me to some links?
Thanks a lot!
 
J

Jon Skeet [C# MVP]

Udi wrote:

However, this fixes the problem:

object [] myArgs = {new int() };
obj.GetType().InvokeMember( "Memory",
BindingFlags.SetProperty | BindingFlags.Public |
BindingFlags.Instance,
null,
obj,
myArgs) // WORKS FINE
);

I guess this is related to a temporary array that is returned from
'ToArray()' and gets lost,
but I still don't really understand what's happening there.
Can anyone please explain to me what's exactly happening behind the
scenes, or point me to some links?

I believe the difference is in terms of what happens to the contents of
the array. Remember that at this stage, the array contains a boxed int
- the same reference which is in the ArrayList in the original sample.

In .NET 1.1, the contents of the box is changed by the out parameter
being set. In .NET 2.0, the array element is replaced with a new boxed
int.

Here's a short but complete program which demonstrates the difference
in behaviour:

using System;
using System.Reflection;

class Test
{
static void Main()
{
object x = 0; // x is a reference to a boxed int
object[] args = new object[]{x};

typeof(Test).GetMethod("DoSomething").Invoke(null, args);
Console.WriteLine("x={0}", x);
Console.WriteLine("args[0]={0}", args[0]);
// Note *reference* equality is used here
Console.WriteLine("x==args[0]? {0}", x==args[0]);
}

public static void DoSomething(out int i)
{
i=10;
}
}

..NET 1.1 results:
x=10
args[0]=10
x==args[0]? True

..NET 2.0 results:
x=0
args[0]=10
x==args[0]? False

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top