Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Да. Диспетчеризация вызова метода по типу аргумента, восстановленного из JSON объекта. Никакой писанины, оно само.
S>А где-нибудь есть пример подобного?
public string Query(string queryString)
{
dynamic queryObject = ObjectToStringConverter.ObjectFromString(queryString);
dynamic @this = this;
var result = @this.Query(queryObject);
return ObjectToStringConverter.ObjectToString(result);
}
public class SomeQuery
{
}
bool Query(SomeQuery query)
{
// do something with queryreturn true;
}
Здравствуйте, Shmj, Вы писали:
S>Хотя бы раз вам помогла возможность писать динамически типизируемый код на C#? Что это был за случай?
Да, оказавшаяся весьма к месту Newtonsoft.Json может возвращать разобранный json в виде dynamic-объекта, в том конкретном случае для меня это было весьма удобно.
Хотя в целом dinamic идейно мне не нравится и по без особой необходимости применять его не стал бы.
Здравствуйте, Shmj, Вы писали:
S>Хотя бы раз вам помогла возможность писать динамически типизируемый код на C#? Что это был за случай?
1. Для работы с COM/COM+ много раз использовал (давно)
2. Один раз писал dynamic dispatch. Примерно, как вот тут описано.
3. C XML бывает удобно работать. Примерно вот так. В юнит-тестах такое часто использовал для подготовки/проверки XML данных.
4. Вообще можно обертки писать к любому нетипизированному хранилищу (XML, JSON, LDAP, REST API, etc.).
Здравствуйте, Shmj, Вы писали:
S>Хотя бы раз вам помогла возможность писать динамически типизируемый код на C#? Что это был за случай?
1. Работа с 1С
2. Создание оберток вместо d["ЧтоТоТам"] d.ЧтоТоТам
3. Например работа с XML, JSON
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladCore, Вы писали:
VC>Здравствуйте, Shmj, Вы писали:
S>>Хотя бы раз вам помогла возможность писать динамически типизируемый код на C#? Что это был за случай?
VC>Про Dapper не слышал?
Я, например, слышал. Только вот вменяемый способ использования dynamic представить не могу, разве что результат квери сразу в json.
Re[3]: dynamic - пригождалось ли в вашей практике?
Здравствуйте, Danchik, Вы писали:
VC>>Здравствуйте, Shmj, Вы писали:
S>>>Хотя бы раз вам помогла возможность писать динамически типизируемый код на C#? Что это был за случай?
VC>>Про Dapper не слышал?
D>Я, например, слышал. Только вот вменяемый способ использования dynamic представить не могу, разве что результат квери сразу в json.
Мда.
public string GetShortVersion(IDbConnection connection, int? commandTimeout)
{
dynamic row = connection.QueryFirst(@"
Select
@@MICROSOFTVERSION Ver32Bit,
SERVERPROPERTY('ProductLevel') Level,
SERVERPROPERTY('ProductUpdateLevel') UpdateLevel",
commandTimeout: commandTimeout);
int ver32Bit = row.Ver32Bit;
string level = row.Level;
string updateLevel = row.UpdateLevel;
int v1 = ver32Bit >> 24;
int v2 = ver32Bit >> 16 & 0xFF;
int v3 = ver32Bit & 0xFFFF;
var ver = new Version(v1, v2, v3);
var ret = new StringBuilder(ver.ToString());
if (!string.IsNullOrEmpty(level) && level != "RTM") ret.Append('-').Append(level);
if (!string.IsNullOrEmpty(updateLevel)) ret.Append('-').Append(updateLevel);
return ret.ToString();
}
Здравствуйте, Mystic Artifact, Вы писали:
MA>Здравствуйте, VladCore, Вы писали:
MA> И зачем же тут динамик? Из-за лени написать что-то вроде
row.Get<int>("Ver32Bit")
?
а если там, в row, внутри public property int Ver32Bit { get; }
2.
ну и семантически идея поъожа на анонимные типы — не надо локальные только данные отжельно описывать в коде.
разница есть конечно и большая, те в compile time генерятся а те в runtime.
3. всякие рефаткоринги Get<T>("field") могут понять а могут и не понять
Re[6]: dynamic - пригождалось ли в вашей практике?
Здравствуйте, VladCore, Вы писали:
VC>а если там, в row, внутри public property int Ver32Bit { get; }
Тогда видимо динамик тем более не нужен же.
VC>2. VC>ну и семантически идея поъожа на анонимные типы — не надо локальные только данные отжельно описывать в коде. VC>разница есть конечно и большая, те в compile time генерятся а те в runtime.
Ничего не понял. Там в даппере вроде бы DapperRow? по сути является очень тупеньким хранилищем этой строки, и интерфейсом навроде IDictionary<string, object>. Таким образом никакая механика не позволит перейти от маппинга значений по именам полей к ординалам, но только теперь код делает дохрена всего неявно. Ну, это на мой личный вкус. Тут уже не раз указывали, что применяют динамик ради синтаксиса.
VC>3. всякие рефаткоринги Get<T>("field") могут понять а могут и не понять
А им строго не надо туда лезть. Основание менять имена полей — только изменение строки запроса. Во всех остальных случаях это вредительство. Если есть рефакторинги которые такое распознают... ну ок. У меня в студии таких правда нет.
Re[7]: dynamic - пригождалось ли в вашей практике?
Здравствуйте, Mystic Artifact, Вы писали:
VC>>а если там, в row, внутри public property int Ver32Bit { get; } MA> Тогда видимо динамик тем более не нужен же.
VC>>2. VC>>ну и семантически идея поъожа на анонимные типы — не надо локальные только данные отжельно описывать в коде. VC>>разница есть конечно и большая, те в compile time генерятся а те в runtime. MA> Ничего не понял. Там в даппере вроде бы DapperRow? по сути является очень тупеньким хранилищем этой строки, и интерфейсом навроде IDictionary<string, object>. Таким образом никакая механика не позволит перейти от маппинга значений по именам полей к ординалам, но только теперь код делает дохрена всего неявно. Ну, это на мой личный вкус. Тут уже не раз указывали, что применяют динамик ради синтаксиса.
VC>>3. всякие рефаткоринги Get<T>("field") могут понять а могут и не понять MA> А им строго не надо туда лезть. Основание менять имена полей — только изменение строки запроса. Во всех остальных случаях это вредительство. Если есть рефакторинги которые такое распознают... ну ок. У меня в студии таких правда нет.
Ты не понял. Сейчас да, DapperRow который реализует IReadOnlyDictionary, но с dynamic это всего лиш внутренняя реализация.
Stackoverflow команде никто не мешает поменять реализацию — заемитиьть
class <>Row_42 {
public int Ver32Bit { get; }
public string Level { get; }
public string UpdateLevel {get; }
...
}
и замемитить итератор:
public IEnumerable<<>Row_42> GetResultset{
while(reader.ReadNext())
{
yeild return new <>Row_42(........);
}
}
Здравствуйте, VladCore, Вы писали:
VC>Stackoverflow команде никто не мешает поменять реализацию — заемитиьть
VC>
VC>class <>Row_42 {
VC> public int Ver32Bit { get; }
VC> public string Level { get; }
VC> public string UpdateLevel {get; }
VC> ...
VC>}
VC>
Да я то понял, только в этом смысла особого нет. Если мы делаем Query<T> — то разумеется, эффективный маппер можно построить и импользовать. А вот построить тип динамически, на основании результата запроса — идея такая себе. У типа банально нет прямых потребителей, потому, что о нем никто не знает ни до компиляции, ни после. Сама по себе "эффективность" такой манипуляции тоже окажется под вопросом, т.к. лукап по словарю не такой уж и медленный, в сравнении с генерацией типа. И самое главное, результирующий код будет генерировать разные типы в зависимости от конкретной версии объектов в БД (в зависимости от изменения вьюх, колонок и т.п.). Получается, что машина введет тип, но гарантий это никак не прибавит.
VC>Как в Linq2Db я хз, но наверно что то похожее?
Давно там не лазил. Насколько я помню строится маппер на существующий тип, используя маппинг ч/з ординалы. Зуб не дам, но вроде было так.
Re[9]: dynamic - пригождалось ли в вашей практике?
Здравствуйте, Mystic Artifact, Вы писали:
VC>>Stackoverflow команде никто не мешает поменять реализацию — заемитиьть
VC>>
VC>>class <>Row_42 {
VC>> public int Ver32Bit { get; }
VC>> public string Level { get; }
VC>> public string UpdateLevel {get; }
VC>> ...
VC>>}
VC>>
MA> Да я то понял, только в этом смысла особого нет. Если мы делаем Query<T> — то разумеется, эффективный маппер можно построить и импользовать. А вот построить тип динамически, на основании результата запроса — идея такая себе. У типа банально нет прямых потребителей, потому, что о нем никто не знает ни до компиляции, ни после. Сама по себе "эффективность" такой манипуляции тоже окажется под вопросом, т.к. лукап по словарю не такой уж и медленный, в сравнении с генерацией типа. И самое главное, результирующий код будет генерировать разные типы в зависимости от конкретной версии объектов в БД (в зависимости от изменения вьюх, колонок и т.п.). Получается, что машина введет тип, но гарантий это никак не прибавит.
Вся эффективность даппера строится на кешировании всего и вся в IDictionary. Вот тут описывается что они юзают в качестве ключа: