Главная > C# > Linq Expression. Пример заполнения DropDownList`а.

Linq Expression. Пример заполнения DropDownList`а.

Потребовалось заполнить три дропдаун листа наборами типизированных данных, которые возвращаются тремя методами. DropDownList заполняется объектами ListItem, у ListItem`ов есть два свойства Value и Text, если подсунуть DropDownList`у в качестве DataSource`а прямо возвращенную коллекцию, то Value и Text у ListItem окажутся одинаковыми, но такой вариант мне не подходил. В качестве другого варианта можно в цикле foreach по коллекции вызывать метод Add(ListItem listItem) на свойстве Items объекта DropDownList или использовать метод Select из Linq прямо на коллекции. Последний вариант мне нравится больше, короче вышло нечто подобное:

service.MethodOne()
                .Select(i => new ListItem {Value = i.Id, Text = i.Name})
                .ToList()
                .ForEach(i => dropDownList1.Items.Add(i));

service.MethodTwo()
                .Select(i => new ListItem {Value = i.ZipCode, Text = i.ZipCode})
                .ToList()
                .ForEach(i => dropDownList2.Items.Add(i));

service.MethodThree()
                .Select(i => new ListItem {Value = string.Format("{0}-{1}", i.Id, i.Prefix) , Text = i.Name})
                .ToList()
                .ForEach(i => dropDownList3.Items.Add(i));

Видно, что это явная дубликация кода, все три варианта заполнения отличаются лишь лямбда-выражениями. Соответственно, можно было бы создать метод, в который необходимо было бы передать эти самые выражения. Вспомнилось, что в .NET был какой-то класс для работы с выражениями. Начав набирать «Expression», студия сама подсказала, что такой класс действительно существует. Создать метод, который получает на вход лямбда-выражения оказалось несложно:

private static void PopulateDropDownList<T>(                                                    
                                                    DropDownList dropDownList,
                                                    Func<IEnumerable<T>> getData,
                                                    Expression<Func<T, string>> expressionValue,
                                                    Expression<Func<T, string>> expressionText)
        {
            getData()
                .Select(l => new ListItem { Value = expressionValue.Compile().Invoke(l), Text = expressionText.Compile().Invoke(l) })
                .ToList()
                .ForEach(i => dropDownList.Items.Add(i));
        }

, где T — это тип данных, соответствующий типу данных, который возвращает метод getData (он же — метод сервиса). Ну а предыдущие методы превратились в следующие записи:

PopulateDropDownList(ddlStocks, () => service.MethodOne(), i => i.Id, i => i.Name);

PopulateDropDownList(ddlSources, () => service.MethodTwo(), i => i.ZipCode, i => i.ZipCode);

PopulateDropDownList(ddlTimePeriods, () => service.MethodThree(), i => FormatToSomething(i), i => FormatToSomethingElse(i));

Не знаю, насколько шустро все это работает, но зато никакой дубликации кода. Прикольная штука, эти экспрешшены.

Categories: C# Tags: , ,
  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.