|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
Интересуют два конкретных примера: 1) Expression<Func<T, TResult>> в Expression<Func<T, T>> 2) Func<T, TResult> в Func<T, T>. Зачем мне это надо? - У меня есть готовая функция, работающая с Expression<Func<T, TResult>> (это тип параметра). Штука в том, что нужный результат можно получить с абсолютно тем же телом этой функции, но работающей с Expression<Func<T>>. Так вот, хочу повторно использовать эту функцию, имея Expression<Func<T>> и передав её в качестве параметра Expression<Func<T, TResult>>, полученный из исходного Expression<Func<T>>. Ну и то же самое для Func - смотря с чем легче получится, с выражениями или с чисто делегатами. Ну и вообще, стоит ли это делать? Может, проще (хотя, конечно, однозначно проще!) скопипастить тело одной функции в другую и дело с концом? У меня сейчас именно что скопипастено. Кто абстрактно не может, могу совсем прямо конкретный пример привести, где это мне нужно. Вот та самая функция: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Вот как я её использую в расширяющих методах: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Как видите, OwnName содерижт тот же код, что и GetMemberName, но не может просто взять и вызвать GetMemberName, как это делает MemberName, из-за несовпадения типов делегатов, с которыми работают их выражения. А хочется просто взять и вызвать готовый метод с конверсией выражения (желательно, в одну строчку - коротко и красиво чтобы было). ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 10:36 |
|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
Могу добавить только, что с MemberName работаю так: myClassObject.MemberName(obj => obj.PropertyOfMyClassObject) а с OwnName так: myClassObject.OwnName(() => myClassObject) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 10:39 |
|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
Я же на днях давал ссылку . Зря ты её не захотел смотреть. :-) Типизация под разные входные выражения: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
Один парсер для разных типов: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 10:56 |
|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
Алексей КЯ же на днях давал ссылку . Зря ты её не захотел смотреть. :-) Типизация под разные входные выражения: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
Один парсер для разных типов: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Т. е. ключевая идея здесь, как я понял - привести входное выражение к простейшему выражению (которым вы выбрали UnaryExpression) и вытаскивание единственного члена этого выражения? Или UnaryExpression выбрал не случайно и другие не подойдут? И другой вопрос. Ваш код подходит только для полей и свойств. Для вытаскивания названий методов вы бы также что-то вроде switch городили в вашем методе GetPropertyPath? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 13:30 |
|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
user7320Т. е. ключевая идея здесь...Ключевая идея здесь в том, что Expression<Func<object>> , Expression<Func<T, object>> , Expression<Любой Делегат> имеют свойство Body типа Expression , по которому можно обобщить доступ к этим выражениям. А на сам парсер можешь не смотреть, он решает чисто мои задачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 13:38 |
|
Конвертация выражений (expressions) и делегатов
|
|||
---|---|---|---|
#18+
Алексей Кuser7320Т. е. ключевая идея здесь...Ключевая идея здесь в том, что Expression<Func<object>> , Expression<Func<T, object>> , Expression<Любой Делегат> имеют свойство Body типа Expression , по которому можно обобщить доступ к этим выражениям. А на сам парсер можешь не смотреть, он решает чисто мои задачи. Короче, я насмотрелся на всякие извращения по конверсии выражений и делегатов. Вы правильно подметили - все эти штуки имеют свойство Body, и даже если использовать эти конверсии - так или иначе вытаскиваешь Body. Но раз уж вытащил - зачем конвертировать? Сразу вытаскиваем имя. Т. е. ну и что, что копипаст - зато без извращений. Вобщем, я оставил свой старый вариант. А ещё я могу вытащить имя любой локальной переменной даже чисто со своим MemberName, который был задуман мной для классов. Просто в качестве входного параметра можно любой объект передать - он всё равно не будет использоваться - а выражение сделать из одной этой локальной переменной. Например: Код: c# 1. 2.
И даже, вроде, особых накладных расходов на это нет никаких. Я теперь вспомнил, что я раньше так и делал. Но потом зачем-то захотел отдельный метод для имён локальных переменных ввести. Дело в том, что пользователь моего метода может знать о том, что вот можно его использовать для вытаскивания имён локальных переменных, только если знает как этот метод устроен внутри - т. е. что он тупо с Body работает. Поэтому и подумал, что надо отдельный метод, само название которого будет говорить, для чего он. Вобщем, оставил у себя всё как было. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.01.2014, 14:40 |
|
|
start [/forum/topic.php?fid=20&fpage=131&tid=1403394]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
33ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
89ms |
get tp. blocked users: |
2ms |
others: | 11ms |
total: | 177ms |
0 / 0 |