Если Вы просто желаете, чтобы люди смогли понять, насколько устаревший они, Мерзавец может сообщить им об этом несколькими довольно простыми способами. Они сравнивают даты последней фиксации на их соединительной линии и Вашей соединительной линии, например. Они могут использовать git cherry
для наблюдения, сколько фиксаций произошло в соединительной линии, которые не присутствуют в их.
, Если бы это - все, которое Вы хотите это для, я искал бы способ обеспечить его без номера версии.
кроме того, я не потрудился бы расширять любезность до любого, если Вы не уверены, что они хотят ее. :)
Везде, где сейчас используется старомодное отражение, и читаемость кода ухудшилась. И, как вы говорите, некоторые сценарии взаимодействия (я иногда работаю с COM).
Это почти все. Если можно избежать использования динамического
, его следует избегать. Проверка времени компиляции, производительности и т.д.
Несколько недель назад я вспомнил эту статью . Когда я впервые прочитал это, я был откровенно возмущен. Но я не осознавал, что не знал, как даже использовать оператор для какого-то неизвестного типа. Я начал задаваться вопросом, какой будет сгенерированный код для чего-то вроде этого:
dynamic c = 10;
int b = c * c;
Используя регулярное отражение, вы не можете использовать определенные операторы. Он сгенерировал довольно много кода, используя некоторые вещи из пространства имен Microsoft
. Скажем так, приведенный выше код намного легче читать :) Приятно, что он работает, но он был также очень медленным: примерно в 10 000 раз медленнее, чем обычное умножение (doh), и примерно в 100 раз медленнее чем интерфейс ICalculator
с методом умножения.
Edit - сгенерированный код, для заинтересованных:
if (<Test>o__SiteContainer0.<>p__Sitea == null)
<Test>o__SiteContainer0.<>p__Sitea =
CallSite<Func<CallSite, object, object, object>>.Create(
new CSharpBinaryOperationBinder(ExpressionType.Multiply,
false, false, new CSharpArgumentInfo[] {
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null),
new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) }));
b = <Test>o__SiteContainer0.<>p__Site9.Target(
<Test>o__SiteContainer0.<>p__Site9,
<Test>o__SiteContainer0.<>p__Sitea.Target(
<Test>o__SiteContainer0.<>p__Sitea, c, c));
Ключевое слово dynamic предназначено для упрощения кода, необходимого для двух сценариев:
Хотя это могло использоваться вне этих сценариев, вероятно, не должно быть .
Мигель де Икаса представил очень интересный вариант использования в своем блоге, здесь (источник включен):
dynamic d = new PInvoke ("libc");
d.printf ("I have been clicked %d times", times);
Если это возможно сделать безопасным и надежным Кстати, это было бы здорово для взаимодействия с машинным кодом.
Я буду использовать его, чтобы упростить свой код, связанный с COM / Interop, где раньше мне приходилось указывать вызываемый член, его параметры и т. Д. (В основном, когда компилятор не знал о существование функции, и мне нужно было описать ее во время компиляции). С динамическим режимом это становится менее громоздким, а код - более компактным.
Это также позволит нам избежать использования шаблона посетителя в некоторых случаях, поскольку теперь возможна множественная отправка
public class MySpecialFunctions
{
public void Execute(int x) {...}
public void Execute(string x) {...}
public void Execute(long x) {...}
}
dynamic x = getx();
var myFunc = new MySpecialFunctions();
myFunc.Execute(x);
... будет вызывать наилучшее соответствие метода во время выполнения, а не разработано во время компиляции