Здравствуйте, ·, Вы писали:
S>>Потому, что IL получается такой, как будто написали
·>S>>Console.WriteLine(string.Concat("You chose ", colour.ToString()));
·>
·>В java я знаю, что такой код сконвертится в String.valueOf(colour), который внутри ещё делает null-check: String valueOf(Object obj) {return obj == null ? "null" : obj.toString(); }. Т.к. c# сдирали с явы, то скорее всего будет что-то очень похожее.
Не "скорее всего", а будет ровно то, что я написал. Это часть спецификации языка, и результат нетрудно
проверить.
·>Но даже если вдруг не так, то не так уж важно, суть в том, что вызов метода ToString находится в 3rd party code, соответственно InterceptsLocation ставить тупо некуда.
Нет, не находится. Там нет никакого 3rd party code. Порождается именно такое AST, прямо в том месте, где идёт вызов WriteLine.
·>Поэтому вся эта затея с магическим ToStringFast очень хрупкая и практически никак не контролируемая, только в бложик написать годится. Если кто-то захочет внедрить подобное в проекте — надо будет сильно стукнуть по башке.
Ничего никуда не стукнет. Потому, что эта штука — оптимизационная. Её задача — не в том, чтобы менять семантику 3rd-party code, а в том, чтобы
оптимизировать свой код.
·>Это всё не поможет. Всё равно остаётся миллион возможностей когда call site окажется за пределами досягаемости компилятора. Недаром я немного другой пример привёл с Logger.Info вместо +, там уж точно метод будет дёргаться хз откуда; так же лесом пойдут все функции и либы форматирования и шаблонизации.
1. Логгеры в дотнете устроены не так, как вы пишете.
2. Опять-таки: если есть какой-то
сторонний код, который собрался что-то там логировать, то при использовании этой техники он просто продолжит работать как работал.
·>Не понял. Если ты имеешь в виду, что появится возможность поменять тело ToString?
Нет, я имею в виду, что непонятно, на какой фазе разбора применяется подстановка. До того, как код будет рассахарен, или после.
Потому что
до рассахаривания никакого вызова ToString() нету: там BinaryOperation сложения, у которой правый аргумент — это Convert.
·>Ну да, это и надо делать, это то что будет полезно и покрывать практически всё возможно необходимое. Делать подмены call site — толку как с козла молока, очень узкий специфичный сценарий, неясно какие проблемы решающий.
Вполне ясно, какие проблемы он решает. В частности, он позволяет в тех местах, где происходит рантайм-анализ всякого разного, включая Expression Trees, подставить компайл-тайм результат.
Иногда можно добиться похожего эффекта ручным редактированием, но это
а) контрпродуктивно и
б) возможно не всегда.
Даже когда таких сценариев "мало", они могут всё ещё существенно повлиять на результат. В частности, какой-нибудь
https://nessos.github.io/LinqOptimizer/ требует везде втыкать AsQueryExpr(), и он всё ещё тратит время на оптимизацию кода в рантайме.
А обсуждаемая фича способна взять и автоматически заменить весь "медленный linq-код" на эквивалентный быстрый без затрат на ручное переписывание кода во время разработки, и анализ выражений во время выполнения.
Если у вас есть приложение, у которого подобные запросы составляют значительную долю вычислительного времени, то банальный импорт пакета и перекомпиляция дадут вам перформанс буст на ровном месте.
Чем плохо-то?