Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
1

Лямбда выражение в качестве параметра метода. Как получить свойство с которым производится операция?

04.12.2015, 09:23. Показов 3068. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!

Нужно в методе принимать лямбду:

C#
1
obj.Get(x=>x.ParentId==5);
Как мне из этой лямбды в методе Get получить имя свойства "ParentId"?

C#
1
2
3
Get(Func<WorkItem, bool> expr){
    //Как получить ParentId
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.12.2015, 09:23
Ответы с готовыми решениями:

Верно ли, что, чтобы передать лямбда выражение в качестве параметра, нужно использовать делегат?
Здравствуйте. Правильно ли я понимаю, что, чтобы передать функцию или лямбда выражение в качестве...

Передача лямбда-функции в качестве параметра
Коллеги, доброго всем времени суток. Помогите, пожалуйста, с такой проблемой. Передаю функцию в...

Константа в качестве параметра метода - как?
Класс Vehicle хранит информацию о транспортных средствах: скорость, направление, имя владельца, id....

Лямбда-выражение с квадратом своего параметра
Создайте лямбда-выражение, которое будет возвращать квадрат своего параметра, и сообщите его с...

11
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
04.12.2015, 09:28 2
вы не путайте мягкое с мокрым.
в методе Get вы вызываете функцию expr, передавая в нее параметры типов WorkItem и bool
C++
1
expr(workItem, boolVal);
0
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
04.12.2015, 09:32  [ТС] 3
Konctantin, в этом и вопрос, как получить то что мне нужно? пробовал использовать LambdaExpression из LINQ, тоже не получилось
0
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
04.12.2015, 11:24 4
ну не знаю, гляньте тут что ли https://msdn.microsoft.com/ru-... 34540.aspx

Добавлено через 21 минуту
Хотя вам скорее всего надо попробовать раскрутить стек вызовов (StackTrace).
1
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
04.12.2015, 11:57  [ТС] 5
Konctantin, Сделал так, хотя оно и не дало то что нужно...
C#
1
2
3
4
5
Get(Expression<Func<WorkItem, bool>> expr){
var lambda = (LambdaExpression)expr;
var left= (MemberExpression)((BinaryExpression)lambda.Body).Left;
string propname = left.Member.Name;
}
Спасибо
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.12.2015, 12:09 6
Лучший ответ Сообщение было отмечено OwenGlendower как решение

Решение

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Linq.Expressions;
 
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = GetName<ConsoleKeyInfo, ConsoleKey>(x => x.Key);
            Console.WriteLine(name);
        }
 
        private static string GetName<T, TResult>(Expression<Func<T, TResult>> member)
        {
            MemberExpression memberExpression = member.Body as MemberExpression;
            if (memberExpression == null)
            {
                memberExpression = (MemberExpression)((UnaryExpression)member.Body).Operand;
            }
            return memberExpression.Member.Name;
        }
    }
}
Думаю дальше разберешься

Если интересно побольше, то у меня похожим образом была сделана библиотечка компараторов:
https://github.com/Pzixel/ZAT/... omparer.cs
https://github.com/Pzixel/ZAT/... rerTest.cs
1
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.12.2015, 12:15 7
KeBJIaP, блин, зачем было 2 темы создавать?..

Кстати нужно понимать, что всё развалится, если вместо поля будет свойство (они с точки зрения экспрешнов различаются).
1
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
04.12.2015, 13:40  [ТС] 8
Psilon, спасибо, однако я не добился успеха идя по этому пути. Я хотел изменять на лету лямбда выражение для запроса к репозиторию в Xml файле. То есть есть метод интерфейса репозитория, принимающий лямбда выражение в терминах объектов WorkItem, я хотел на лету его транслировать для запроса к XDocument для поиска соответствующих элементов, чтобы не конвертировать массу записей WorkItem.
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.12.2015, 20:12 9
KeBJIaP, ну звучит адекватно, а с чем проблема?
0
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
06.12.2015, 11:32  [ТС] 10
Psilon, Ну например, лямбда для объекта
C#
1
(WorkItem x) => x.Id == 5;
должна транслироваться в что-то подобное:
C#
1
(XElement x) =>  Int32.Parse(x.Attribute("Id").Value) == 5 ;
Я пытался сделать через метод Update() в классе типа выражения(например, BinaryExpression), но он принимает непонятную магию и заставить работать это все не вышло, а ведь это только самый простой случай
0
970 / 773 / 171
Регистрация: 12.04.2009
Сообщений: 1,700
06.12.2015, 11:43 11
Я подобные манипуляции делал с помощью IL генератора, создавая динамический метод.
С експрешинами по идее тоже так можно делать, но почему-то они мне показались сложнее, видимо надо их будет по изучать.
1
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
06.12.2015, 13:45 12
KeBJIaP, посмотрите выше мой пример с компараторами. Например в тестах виден следующий код:
C#
1
var customComparer = CustomComparer<Test>.New(t => t.A).Add(t => t.B).Add(t => t.C).Add(t => t.D);
С помощью вызова этой цепочки методов получается следующая лямбда:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.Lambda #Lambda1<System.Comparison`1[XLinq.Test.Comparers.CustomComparerTest+Test]>(
    XLinq.Test.Comparers.CustomComparerTest+Test $x,
    XLinq.Test.Comparers.CustomComparerTest+Test $y) {
    .Block(System.Int32 $compareA) {
        $compareA = .Call ($x.A).CompareTo($y.A);
        .If ($compareA != 0) {
            .Return #Label1 { $compareA }
        } .Else {
            .Block(System.Int32 $compareB) {
                $compareB = .Call ($x.B).CompareTo($y.B);
                .If ($compareB != 0) {
                    .Return #Label1 { $compareB }
                } .Else {
                    .Block(System.Int32 $compareC) {
                        $compareC = .Call ($x.C).CompareTo($y.C);
                        .If ($compareC != 0) {
                            .Return #Label1 { $compareC }
                        } .Else {
                            .Block(System.Int32 $compareD) {
                                $compareD = .Call ($x.D).CompareTo($y.D);
                                .If ($compareD != 0) {
                                    .Return #Label1 { $compareD }
                                } .Else {
                                    .Default(System.Void)
                                }
                            }
                        }
                    }
                }
            }
        };
        .Label
            0
        .LabelTarget #Label1:
    }
}
Поэтому задача выше легко выполнима
1
06.12.2015, 13:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.12.2015, 13:45
Помогаю со студенческими работами здесь

Лямбда выражение в качестве передаваемого аргумента функции
Добрый день! Подскажите пожалуйста, могу ли я в функциях библиотеки Qt использовать в качестве...

Задача. Лямбда-выражение в параметрах метода
Прохожу &quot;Java. Базовый курс&quot; на степике. Туплю сказочно. Решить задачу за меня не прошу. Но вопрос...

Enum в качестве параметра метода
Уважаемые форумчане ! Совершенно неожиданно для меня вызвало трудности передачи Enum в качестве...

Слово this в качестве параметра для метода
Есть вот такой код, в нём 2 метода Insert, служат они для добавления в бинарное дерево нового...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru