Почему я получаю исключение RuntimeBinderException, используя json.net с динамическим вызовом метода

Почему, когда я использую dynamic с json.net, я получаю исключение привязки во время выполнения, а затем вызываю метод без приведения, но я могу выполнять назначения без проблем

private static void Main()
{
    dynamic json = JObject.Parse("{\"Test\":23}");
    var t = json.Test;
    int a = t; //Success
    Prop = t; //Success
    Func(t); //RuntimeBinderException
}

private static void Func(int i){}

private static int Prop { get; set; }

Когда я привожу его к правильному типу, ошибок нет, но я бы предпочел этого не делать. Я что-то не так делаю, это проблема в библиотеке json.net или языковое ограничение.

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


person Glitch    schedule 09.11.2011    source источник
comment
Не могли бы вы опубликовать полное сообщение об исключении?   -  person Bryan Crosby    schedule 09.11.2011


Ответы (2)


Это связано с тем, что json.Test возвращает JValue, а JValue имеет динамическое TryConvert. Поэтому, если вы выполняете неявное статическое преобразование, указав его на int или приведя к int, он во время выполнения вызовет это TryConvert, и вы добьетесь успеха. Однако, если вы используете эту динамически типизированную переменную в аргументе метода, среда выполнения С# ищет метод с именем Func с аргументом, который лучше всего соответствует «JValue», он не будет пытаться вызывать «TryConvert» для каждой перестановки возможного метода (даже если это только один), поэтому вы получаете ошибку привязки времени выполнения.

Таким образом, самое простое решение — просто выполнять приведение типов при каждом вызове или устанавливать статически типизированную переменную каждый раз, когда вы хотите передать JValue в качестве аргумента.

На самом деле есть более общий вопрос и ответ на эту же проблему, если вы ищете дополнительную информацию: Передать динамическую переменную в статическом параметре метода в C# 4

person jbtule    schedule 10.11.2011
comment
Это мне очень помогло. Спасибо большое. Какое странное поведение... - person Sebastian Edelmeier; 08.11.2018

private static void Func (динамический i) {}

решит вопрос.

person ratneshsinghparihar    schedule 09.11.2011
comment
да, но что мне делать, если у меня нет контроля над сигнатурой метода, который я вызываю. - person Glitch; 09.11.2011