Теперь, когда С# поддерживает именованные параметры, я проверял, был ли он реализован так же, как это сделал VB, и обнаружил, что есть небольшая разница. Возьмем, например, библиотечную функцию:
public static void Foo(string a, string b)
{
Console.WriteLine(string.Format("a: {0}, b: {1}", a, b));
}
В С#, если вы вызываете это следующим образом:
Foo(a: "a", b: "b");
Компилятор создает следующие инструкции IL:
.locals init (
[0] string CS$0$0000,
[1] string CS$0$0001)
L_0000: nop
L_0001: ldstr "a"
L_0006: stloc.0
L_0007: ldstr "b"
L_000c: stloc.1
L_000d: ldloc.0
L_000e: ldloc.1
L_000f: call void [TestLibrary]TestLibrary.Test::Foo(string, string)
L_0014: nop
L_0015: ret
Что означает следующий код С#:
string CS$0$0000 = "a";
string CS$0$0001 = "b";
Test.Foo(CS$0$0000, CS$0$0001);
В VB, если вы вызываете это так:
Foo(a:="a", b:="b")
Компилятор создает следующие инструкции IL:
L_0000: nop
L_0001: ldstr "a"
L_0006: ldstr "b"
L_000b: call void [TestLibrary]TestLibrary.Test::Foo(string, string)
L_0010: nop
L_0011: nop
L_0012: ret
Что означает следующий код VB:
Foo("a", "b");
То, как VB это требует, требует гораздо меньше вызовов команд, так есть ли какое-то преимущество в том, как С# реализует его? Если вы не используете именованные параметры, С# производит то же, что и VB.
EDIT. Теперь, когда мы определили, что дополнительные инструкции исчезнут в режиме деблокирования, есть ли у них определенная причина присутствовать в режиме отладки? VB действует одинаково в обоих режимах, а С# не вставляет дополнительные инструкции при вызове метода обычно без именованных параметров (в том числе при использовании необязательных параметров).