I’m experimenting with DynamicObject. One of the things I try to do is setting the values of ref/out arguments, as shown in the code below. However, I am not able to have the values of i and j in Main() set properly (even though they are set correctly in TryInvokeMember()). Does anyone know how to call a DynamicObject object with ref/out arguments and be able to retrieve the values set inside the method?
class Program
{
static void Main(string[] args)
{
dynamic proxy = new Proxy(new Target());
int i = 10;
int j = 20;
proxy.Wrap(ref i, ref j);
Console.WriteLine(i + ":" + j); // Print "10:20" while expect "20:10"
}
}
class Proxy : DynamicObject
{
private readonly Target target;
public Proxy(Target target)
{
this.target = target;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
int i = (int) args[0];
int j = (int) args[1];
target.Swap(ref i, ref j);
args[0] = i;
args[1] = j;
result = null;
return true;
}
}
class Target
{
public void Swap(ref int i, ref int j)
{
int tmp = i;
i = j;
j = tmp;
}
}
Update 7/15:
Microsoft claims to have fixed the issue for the next release of .NET http://connect.microsoft.com/VisualStudio/feedback/details/543101/net-4-0s-dynamicobject-doesn-t-set-ref-out-arguments
Update 9/8/2012:
Tested using VS.NET 2012 with both .NET 4.0 and 4.5, confirm: it’s already fixed.
This looks like it could be a bug – probably in
DynamicObject. If you add aWrapmethod toProxylike this:Then even though this is still called dynamically (i.e. the code in
Mainstays the same) the code works… so at least the general “how does a dynamic object work” layer supports pass-by-reference.I suspect if this is indeed a bug in the DLR, it may be too late to fix for .NET 4 – but it’s worth reporting on Connect anyway so it can be fixed in a service pack. Alternatively, if this is a deliberate restriction/limitation, it should be clearly documented in MSDN (which it isn’t at the moment, as far as I can see).