Когда добавляли в C# слово dynamic видимо основное назначение было в интеграции с COM. Но оказалось, что его можно весьма неплохо применить и в других задачах.
Я столкнулся с необходимостью его использования при загрузке и показе нескольких таблиц из базы данных при помощи RIA+EF.Если на пальцах, то есть метод, который принимает Generic тип и Action, в которые передается параметр того же типа. Мне надо вызвать этот метод для 10+ разных типов.
Entity Framework для меня сгенерил типы, RIA сервисы методы для получения их из базы данных. Я, в целях эмуляции заменил вот на такой аналог:
Ну и соответственно у RIA сервисов есть метод, который асинхронно загружает данные. Его аналог будет иметь вид:
Как видим он является Generic методом. Так вот, мне надо было возвращенные коллекции отображать в DataGrid-е, в зависимости от того, какой метод загрузки выберет пользователь. Вариант с 10+ кнопками и кодом вида:
для каждого справочника мне писать было лень. И я сделал следующий финт ушами:
1. Объявил словарь названий справочников-методов для их загрузки:
4. На событие изменения выбранного элемента дописать вот такой обработчик:
Собственно все.
Выглядеть это все будет вот так:
В чем плюсы? В том, что в первом случае мне придется создать 10+ кнопок, 10+ обработчиков клика, 10+ методов показа данных. А во втором случае в строке со звездочкой (из пункта 2) дописать добавление названий справочников и методов их загружающих.
Ну и в завершении, как это выглядит в реальном приложении:
Собственно все.
P.s. Если кто не очень понял, зачем тут все таки dynamic обратите внимание на метод ShowData, который получает списки разных объектов, и не жужжит. Для тех кто не в курсе, такие приведения:
не работают. А через dinamyc все даже вполне себе работает.
Я столкнулся с необходимостью его использования при загрузке и показе нескольких таблиц из базы данных при помощи RIA+EF.Если на пальцах, то есть метод, который принимает Generic тип и Action, в которые передается параметр того же типа. Мне надо вызвать этот метод для 10+ разных типов.
Entity Framework для меня сгенерил типы, RIA сервисы методы для получения их из базы данных. Я, в целях эмуляции заменил вот на такой аналог:
class First { public int Value { get; set; } } private List<First> ReciveFirst() { List<First> result = new List<First>(); result.Add(new First() { Value = 3 }); result.Add(new First() { Value = 1 }); result.Add(new First() { Value = 7 }); return result; } class Second { public string Item { get; set; } } private List<Second> ReciveSecond() { List<Second> result = new List<Second>(); result.Add(new Second() { Item = "g" }); result.Add(new Second() { Item = "b" }); result.Add(new Second() { Item = "e" }); return result; }
Ну и соответственно у RIA сервисов есть метод, который асинхронно загружает данные. Его аналог будет иметь вид:
private void LoadData(Func<List > p_dataReciver, Action<List > p_callBack) { Action act = () => { Thread.Sleep(1000); // Долгая операция по сети p_callBack(p_dataReciver()); // Возврат загруженных данных }; act.BeginInvoke(null, null); }
Как видим он является Generic методом. Так вот, мне надо было возвращенные коллекции отображать в DataGrid-е, в зависимости от того, какой метод загрузки выберет пользователь. Вариант с 10+ кнопками и кодом вида:
private void button1_Click(object sender, RoutedEventArgs e) { LoadData<First>(ReciveFirst, ShowFirst); } private void ShowFirst(List<First> p_items) { Dispatcher.BeginInvoke((Action)(() => dgItems.ItemsSource = p_items)); }
для каждого справочника мне писать было лень. И я сделал следующий финт ушами:
1. Объявил словарь названий справочников-методов для их загрузки:
Dictionary<string, dynamic> _methods = null;2. Загрузить в него названия справочников и методы их возвращающие (там звездочка, о ней ниже):
_methods = new Dictionary<string, dynamic>(); _methods.Add("Первый", (Func<List<First>>)ReciveFirst); _methods.Add("Второй", (Func<List<Second>>)ReciveSecond); //*3. Загрузить ключи в список:
lbNames.ItemsSource = _methods.Keys;
4. На событие изменения выбранного элемента дописать вот такой обработчик:
private void lbNames_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (lbNames.SelectedItem != null) { LoadData(_methods[(string)lbNames.SelectedItem], (Action<dynamic>)ShowData); } }5. Ну и собственно изменить метод показа:
private void ShowData(dynamic p_list) { Dispatcher.BeginInvoke((Action)(() => dgItems.ItemsSource = p_list)); }
Собственно все.
Выглядеть это все будет вот так:
В чем плюсы? В том, что в первом случае мне придется создать 10+ кнопок, 10+ обработчиков клика, 10+ методов показа данных. А во втором случае в строке со звездочкой (из пункта 2) дописать добавление названий справочников и методов их загружающих.
Ну и в завершении, как это выглядит в реальном приложении:
Собственно все.
P.s. Если кто не очень понял, зачем тут все таки dynamic обратите внимание на метод ShowData, который получает списки разных объектов, и не жужжит. Для тех кто не в курсе, такие приведения:
не работают. А через dinamyc все даже вполне себе работает.
Комментариев нет:
Отправить комментарий