'Динамичный' C# 4.0 не устанавливает касательно / аргументов

Я экспериментирую с DynamicObject. Одна из вещей, которые я пытаюсь сделать, устанавливает значения ref/out аргументы, как показано в коде ниже. Однако я не могу иметь значения i и j в Main() набор правильно (даже при том, что они установлены правильно в TryInvokeMember()). Делает любой знает, как назвать a DynamicObject объект с ref/out аргументы и смочь получить набор значений в методе?

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;
    }
}

Обновление 7/15: Microsoft утверждает, что устранила проблему для следующего выпуска.NET http://connect.microsoft.com/VisualStudio/feedback/details/543101/net-4-0s-dynamicobject-doesn-t-set-ref-out-arguments

Обновление 08.09.2012: Протестированное использование VS.NET 2012 и с.NET 4.0 и с 4.5, подтвердите: это уже фиксируется.

11
задан Buu Nguyen 8 September 2012 в 22:00
поделиться

3 ответа

Похоже, что могла быть ошибкой - вероятно, в DynamicObject . Если вы добавите метод Wrap к Proxy следующим образом:

public void Wrap(ref int x, ref int y)
{
    target.Swap(ref x, ref y);
}

Тогда, даже если он по-прежнему вызывается динамически (т.е. код в Main остается прежним) код работает ... так что, по крайней мере, общий уровень «как работает динамический объект» поддерживает передачу по ссылке.

Я подозреваю, что если это действительно ошибка в DLR, может быть уже слишком поздно исправлять .NET 4, но в любом случае стоит сообщить о Connect , чтобы это могло быть исправлено в сервис-паке. В качестве альтернативы, если это преднамеренное ограничение / ограничение, оно должно быть четко задокументировано в MSDN (чего, насколько я понимаю, на данный момент нет).

5
ответ дан 3 December 2019 в 09:19
поделиться

Короче говоря, DynamicObject не поддерживает передачу по ссылке, поэтому то, что вы хотите сделать, напрямую невозможно.

2
ответ дан 3 December 2019 в 09:19
поделиться

Это не ошибка. Как уже было сказано здесь, DynamicObject не поддерживает параметры ref и out в TryInvokeMember. Все, что передается в этот метод, обрабатывается «по значению». Вкратце, метод TryInvokeMember просто игнорирует эти ключевые слова, и поэтому ваш метод не работает.

Если вы последуете предложению Джона Скита и создадите свой собственный метод Wrap в классе, унаследованном от DynamicObject, это будет немного другой сценарий. Рабочий процесс выглядит следующим образом: при вызове метода для DynamicObject связыватель времени выполнения C # сначала ищет метод в самом классе. Если он может его найти, он вызывает этот метод. На этом этапе информация о параметрах «ref» и «out» все еще сохраняется. Если он не может найти такой метод, он вызывает метод TryInvokeMember и просто выдает информацию о ключевых словах «ref» и «out» и начинает обрабатывать все как «по значению». Помните, что DynamicObject должен поддерживать взаимодействие с другим языком, который может не иметь всех функций C #.

Правда, в документации сейчас отсутствует информация о «ref» и «out». Я добавлю его в следующее обновление документации.

5
ответ дан 3 December 2019 в 09:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: