C#4.0'vynamic'不设置ref/out参数

Buu*_*yen 11 c# dynamic pass-by-reference

我在试验DynamicObject.我尝试做的一件事是设置ref/ outarguments 的值,如下面的代码所示.但是,我不能够拥有的价值观 i,并jMain()正确设置(即使它们被正确设定TryInvokeMember()).有没有人知道如何DynamicObject使用ref/ outarguments 调用对象并能够检索方法中设置的值?

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新7/15: Microsoft声称修复了下一版.NET的问题http://connect.microsoft.com/VisualStudio/feedback/details/543101/net-4-0s-dynamicobject-doesn-t-set -REF出论点

2012年9月8日更新:使用VS.NET 2012与.NET 4.0和4.5进行测试,确认:它已经修复.

Jon*_*eet 5

这看起来可能是一个错误 - 可能在DynamicObject.如果你添加一个像这样的Wrap方法Proxy:

public void Wrap(ref int x, ref int y)
{
    target.Swap(ref x, ref y);
}
Run Code Online (Sandbox Code Playgroud)

然后即使这仍然是动态调用的(即代码Main保持不变)代码也可以工作......所以至少一般的"动态对象如何工作"层支持pass-by-reference.

我想,如果这真的在DLR的错误,它可能为时已晚修为.NET 4 -但它是值得的报告连接反正所以它可以固定在一个服务包.或者,如果这是一个故意的限制/限制,它应该在MSDN中清楚地记录(据我所知,目前不是这样).


Ale*_*ina 5

这不是一个错误.正如在此处所述,DynamicObject不支持TryInvokeMember中的ref和out参数.传递给此方法的所有内容都是"按值"处理的.不久,TryInvokeMember方法只是忽略了这些关键字,这就是为什么你的方法不起作用的原因.

如果您遵循Jon Skeet建议并在继承自DynamicObject的类中创建自己的Wrap方法,则这将是一个稍微不同的场景.工作流程如下所示:当存在对DynamicObject的方法调用时,C#运行时绑定程序首先在类本身中查找该方法.如果可以找到一个,则调用此方法.此时,仍然保留有关"ref"和"out"参数的信息.如果它找不到这样的方法,它会调用TryInvokeMember方法并简单地抛出关于"ref"和"out"关键字的信息,并开始将每个方法视为"按值".请记住,DynamicObject必须支持与其他语言的互操作性,而其他语言可能没有所有C#功能.

没错,文档中现在没有关于"ref"和"out"的信息.我将把它添加到下一个文档更新中.