Подтвердить что ты не робот

Почему дерево выражений не может содержать спецификацию именованных аргументов?

Используя AutoMapper, я попал туда, где именованный аргумент был бы очень приятным:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, isAdvanced: false)))

Но компилятор закричал на меня:

Дерево выражений может не содержать спецификацию названных аргументов

Поэтому мне пришлось вернуться к:

.ForMember(s => s.MyProperty, opt => opt.MapFrom(s => BuildMyProperty(s, false)))

Кто-нибудь знает, почему компилятор запрещает именованные аргументы в этой ситуации?

4b9b3361

Ответ 1

Рассмотрим следующее:

static int M() { Console.Write("M"); return 1; }
static int N() { Console.Write("N"); return 2; }
static int Q(int m, int n) { return m + n; }
...
Func<int> f = ()=>Q(n : N(), m: M());
Expression<Func<int>> x = ()=>Q(n : N(), m: M());
Func<int> fx = x.Compile();
Console.WriteLine(f());
Console.WriteLine(fx());

Вы согласны, я надеюсь, что последние две строки должны делать то же самое, не так ли? Для печати NM3.

Теперь, какие вызовы библиотеки дерева выражений вам бы хотелось, чтобы преобразование дерева выражений для генерации обеспечило это? Их нет! Поэтому мы сталкиваемся со следующими вариантами:

  • Реализация функции в библиотеке дерева выражений. Добавьте преобразование в дерево выражений, понижающее движок, который сохраняет порядок выполнения именованных аргументов. Внедрить код в методе Compile, который учитывает порядок выполнения.
  • Сделать x = ()=>Q(n : N(), m: M()); фактически реализовано как x = ()=>Q(M(), N()); и несовместимо с версией дерева без выражения.
  • Запретить именованные аргументы в деревьях выражений. Внесите в это сообщение об ошибке.

(1) приятно, но дорого. (2) является не стартером; мы не можем с чистой совестью представить такую ​​ "гочу". (3) дешево, но раздражает.

Мы выбрали (3).