Здравствуйте, vdimas, Вы писали:
V>Вот так нет:
V>V>Expression<Func<int, Tuple<int, int>>> t2 = a => Tuple.Create(a, a);
V>
Да это непринципиально. Принципиально, что нельзя написать a=>(a, a).
Это сильно портит, к примеру,
синтаксис возврата нескольких массивов в linq2d.
V>А как вообще сюда напишешь расширение, если Expression порождает сам компилятор?
Вот так:
https://github.com/bartdesmet/ExpressionFutures/tree/master/CSharpExpressions
То есть сами Expression есть, а вот компилятор их порождать не умеет.
V>Т.е. блоки для Expression нельзя.
Да, это хорошо известный факт. Мы это обсуждали в прошлый раз в ветке про linq2d.
С точки зрения применения Expression Trees для разнообразной работы вроде "Давайте пользователь соберёт абстрактный pipeline обработки каких-то данных, а я из него сделаю монолитный эффективный метод без лишних аллокаций" это плохо.
С точки зрения "я хочу писать Queryable Provider" это хорошо. Потому, что мне не нужно писать код для обработки случаев вроде
from p in Person where {var s = new StringBuilder(); foreach(var ch in p.Name} if (p.IsLetterOrDigit) s.Append(ch); return s.ToString()=="John";} select p
V>Кароч, там еще пилить и пилить...
Коротко, там есть два основных класса проблем:
1. Не все языковые конструкции имеют аналог в виде Expression. Решается, к примеру, кодом Барта де Смета.
2. Не все типы Expression (даже из стандартной библиотеки) можно породить компилятором из лямбда-синтаксиса. Вот это решается только коммитом в компилятор шарпа.
Актуальность каждой из проблем зависит от решаемой задачи.