它们实际上是相同的生成的 IL 代码,只有微小的 差异,然而…它们可能会被 JIT编译器 和优化器编译成完全相同的指令。
鉴于此
private (String hello,string world) GetHelloAndWorldStrings()
{
return ("asdsd","sadfsdf");
}
...
public int Test1()
{
var asd = GetHelloAndWorldStrings();
if (asd.hello == "hello" && asd.world == "world")
return 1;
return 0;
}
public int Test2()
{
var (hello, world) = GetHelloAndWorldStrings();
if (hello == "hello" && world == "world")
return 1;
return 0;
}
基本上会被表达为
发出。
public int Test1()
{
ValueTuple<string, string> helloAndWorldStrings = GetHelloAndWorldStrings();
if (helloAndWorldStrings.Item1 == "hello" && helloAndWorldStrings.Item2 == "world")
{
return 1;
}
return 0;
}
public int Test2()
{
ValueTuple<string, string> helloAndWorldStrings = GetHelloAndWorldStrings();
string item = helloAndWorldStrings.Item1;
string item2 = helloAndWorldStrings.Item2;
if (item == "hello" && item2 == "world")
{
return 1;
}
return 0;
}
您可以在此处查看IL
以下是发布版本中的示例
C.Test1()
L0000: push ebp
L0001: mov ebp, esp
L0003: push esi
L0004: mov ecx, [0x11198648]
L000a: mov esi, [0x1119864c]
L0010: mov edx, [0x11198650]
L0016: call System.String.Equals(System.String, System.String)
L001b: test eax, eax
L001d: je short L0038
L001f: mov edx, [0x11198654]
L0025: mov ecx, esi
L0027: call System.String.Equals(System.String, System.String)
L002c: test eax, eax
L002e: je short L0038
L0030: mov eax, 1
L0035: pop esi
L0036: pop ebp
L0037: ret
L0038: xor eax, eax
L003a: pop esi
L003b: pop ebp
L003c: ret
vs
C.Test2()
L0000: push ebp
L0001: mov ebp, esp
L0003: push esi
L0004: mov ecx, [0x11198648]
L000a: mov esi, [0x1119864c]
L0010: mov edx, [0x11198650]
L0016: call System.String.Equals(System.String, System.String)
L001b: test eax, eax
L001d: je short L0038
L001f: mov edx, [0x11198654]
L0025: mov ecx, esi
L0027: call System.String.Equals(System.String, System.String)
L002c: test eax, eax
L002e: je short L0038
L0030: mov eax, 1
L0035: pop esi
L0036: pop ebp
L0037: ret
L0038: xor eax, eax
L003a: pop esi
L003b: pop ebp
L003c: ret
简而言之,为此担忧所得的净收益是负5分钟,这是您永远无法回到过去的时间。
Item1
和Item2
。这些名称仅用于可读性,并且仅在编译时可用。IL 显示它们使用Item1
和Item2
,无论您将它们命名为什么(ValueTuple 是一个像其他结构体一样具有字段的结构体)-例如:valuetype [System.Runtime]System.ValueTuple``2<int32, int32>::Item1
。 - Zach Sawif (helloAndWorld == ("hello","world"))
。 - Panagiotis Kanavos