Обратите внимание, что компилятор C# 4.0 при компиляции под .NET 3.5 и ниже не будет автоматически генерировать перегрузки метода с параметрами, указанных как необязательные (достаточно много пользователей ожидали такое поведение). Однако он будет отмечать параметры псевдоатрибутом [System.Runtime.InteropServices.Optional] и вписывать в метаданные параметров их значения по-умолчанию, что позволит воспользоваться ими в языках для CLR 2.0, поддерживающих необязательные параметры.
dynamic — нет, он требует сборку Microsoft.CSharp.dll, которая есть и будет только для .NET 4.0. Но реально написать свою такую же для .NET 3.5, возможно в скором времени появится аналоги Linq bridge, только для dynamic.
Да просто рано ещё таким библиотекам появляться. Задача достаточно трудоёмкая, в Microsoft.CSharp.dll по сути зашиты все правила C# overload resolution, реализовано call-site кэширование и много другого прочего…
Поставил таки студию, динамик действительно не компилируется
Predefined type 'Microsoft.CSharp.RuntimeBinder.Binder' is not defined, а вот ковариантности вроде работают.
Ко-/контравариантность будут работать во всех аспектах, кроме рантаймных.
Дело в том, что ко-/контравариантность введена на уровне рантайма .NET 4.0, теперь опкоды MSIL, такие как castclass и isinst (операторы as и is в C#) считают, например, что IEnumerable<string> можно скастить в рантайме к IEnumerable<object>.
То есть в .NET 3.5 можно переменной IEnumerable<object> присвоить IEnumerable<string>, но вот xs is IEnumerable<object> (при переменной IEnumerable<string> xs) будет возвращать false.
То есть полного поведения .NET 4.0 при компиляции под .NET 3.5 получить не получится.
Извините, если лезу не в свою тарелку, 2 недели назад я читал данную статью, скорее всего она ваша, но я тут недавно и при регистрации, прочитал: Хабр — не ЖЖ и не центр мирового кросспостинга. Не нужно копировать свои посты из других блогов и сайтов, указывая, что ранее они были опубикованы в другом месте. Используйте топики-ссылки.
Я воспользовался данным советом и не стал копировать пока свою единственную статью, а сделал топик-ссылку, интересно где правда, кому верить? :|
> указывая, что ранее они были опубикованы в другом месте
Так вы можете разместить свою статью здесь полностью, не указывая, что она из другого блога. Никто не мешает параллельно публиковать статьи на Хабре и блоге.
В C# 4.0 точно такое же поведение, как в C++. Будет подставлено значение по-умолчанию от метода, определённого в типе, который будет известен статически на момент компиляции, то есть в Вашем случае известно будет что a — типа A и подставлено будет 0.
* Запретить optional parameters для override-методов — почему должна быть нарушена некая «консистентность», чем они хуже невиртуальных методов?
* Требовать в override указывать точно такое же значение — значение по-умолчанию может быть достаточно сложно в записи и требование от юзера копипасты не выглядит верным решением.
* Забирать из метаданных переопределяемого метода значение по умолчанию и запретить задавать другое — возможно это было бы лучшим решением. Но интересно, могут ли быть реально обоснованные причины изменять значение по умолчанию в override?
Не думаю, что это всё вообще будет составлять проблему, так как в C# значительно лучше развит intellisense, который при вызове всегда покажет какое значение реально будет использовано :)))
В рефлекторе видно так: void Foo([Optional, DefaultParameterValue(true)] bool ensureIsUpToDate)
Про отличие между DoSomething(y:2, x:1) и DoSomething(x:1, y:2) надо было рассказать подробнее. Данная форма вызова меняет порядок вычисления атрибутов. Скажем код ниже
— class Test
{
private int F1()
{
throw new FirstException();
}
private int F2()
{
throw new SecondException();
}
private void DoSomething(int x = 0, int y = 0)
{
}
public Test()
{
DoSomething(y: F2(), x: F1())
}
}
Test t = new Test();
— выбросит исключение типа SecondException
Передача последовательности в качестве не именованых параметров, но лучше передача словаря именованых параметров
например в питоне
d = dict(p1=1, p2=2, p3=3) # словарь
def f2(p1,p2): #функция которая получает именованые параметры р1 и р2
print p1, p2
f2(**d) #развертка словаря в параметры (р3 будет проигнорирован, р1 и р2 будут 1 и 2
По поводу C#: если Вы поразмыслите чуток как почему это работает в python, то возможно осознаете, что эта фича хорошо всписывается только в динамические языки ;))) В C# пришлось бы делать медленный вызов через механизм отражения или генерировать много call-site кода ради сомнительной удобности :) Да ещё и обратите внимание, что в python нету перегрузки методов как таковой ;)
Да. В этом то и дело…
В питоне оно конечно все по другому. Проблема в том, что в С# пытаются притащить куски ФП и динамики, уже не первую версию. Вот так и по частям перетаскивают, как по мне, чуть инвалидно получается. Хотя, это не мешает мне уже который год зарабатывать используя С#
Это проблема?
Что плохого в том, что в язык приобретает черты других парадигм?
Где грань «проблемы», что надо поддерживать C#, чтобы быть не хуже динамических языков? Передача словаря, как параметров — это настолько частая фича в динамических языках, что без неё язык можно считать ущербным?
Реально было бы лучше, если бы язык был чисто объектно-ориентированным?
Необязательные параметры и именованные аргументы в C#4