объединение действия со строкой с использованием dynamics

#c# #c#-4.0

#c# #c #-4.0

Вопрос:

У меня есть следующий код на C#:

 Action a = new Action(() => Console.WriteLine());
dynamic d = a;
d  = "???";
Console.WriteLine(d);
  

и результат является

Система.Действие???

в то время как если вы добавите int вместо строки в d, это вызовет исключение.

Не могли бы вы, пожалуйста, объяснить, почему это происходит?

Ответ №1:

Я думаю, это происходит потому, что при использовании d = "???"; d преобразуется в строку (используя ToString() метод по умолчанию, который принимает имя объекта), а затем добавляется «???» и записывается в консоль.
Если вы попытаетесь использовать d = 2 , это не удастся, потому что нет способа по умолчанию преобразовать действие в целое число. То же самое для других типов…

Комментарии:

1. если я использую какой-либо другой тип для ‘a’, это выдаст исключение

2. @OrlandoWilliam: да, конечно. Причина в том (я пытался объяснить в своем ответе, возможно, я был не совсем ясен, извините), что по умолчанию не существует «конвертера» между действием и другими типами, кроме string…

3. @OrlandoWilliam: Нет, этого не будет. Любой объект может быть преобразован в строку таким образом. Попробуйте: object a = 2; a = "???"; Console.WriteLine(a); , например.

4. отредактировано @StriplingWarrior.. это не другой тип для ‘a’, это строка, которую я добавляю, которую я изменяю… и это не просто какой-то другой тип, это int, извините.

Ответ №2:

Добавление a string к чему-либо в .NET приведет к вызову .ToString метода этой вещи, который будет рассматривать добавление как объединение строк. То же самое произошло бы, если бы вы не использовали dynamic .

 Action a = new Action(() => Console.WriteLine());
Console.WriteLine(a   "???"); // outputs "System.Action???"
  

Любой Action вернет значение System.Action при вызове его .ToString метода.

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

 object a = new Action(() => Console.WriteLine());
a = a   "???"; // The same as: a = a.ToString()   "???";
Console.WriteLine(a);
  

Комментарии:

1. компилятор не разрешил бы этого, если бы я не использовал dynamic

2. @OrlandoWilliam: Уверен, что так и будет, если вместо этого вы приведете d в качестве объекта. Смотрите мое обновление.

3. вы правы, я изменил кое-что еще, проверяя другие вещи, вот почему это вызвало исключение