gpt4 book ai didi

c# - KeyValuePair.ToString 实现细节

转载 作者:太空宇宙 更新时间:2023-11-03 21:43:36 26 4
gpt4 key购买 nike

最近在做其他事情时,我在 KeyValuePair<TKey, TValue>.ToString() implementation 上遇到了一段有点奇怪的代码.

public override string ToString()
{
StringBuilder stringBuilder = StringBuilderCache.Acquire(16);
stringBuilder.Append('[');
if (this.Key != null)
{
StringBuilder arg_33_0 = stringBuilder;
TKey tKey = this.Key;
arg_33_0.Append(tKey.ToString());
}
stringBuilder.Append(", ");
if (this.Value != null)
{
StringBuilder arg_67_0 = stringBuilder;
TValue tValue = this.Value;
arg_67_0.Append(tValue.ToString());
}
stringBuilder.Append(']');
return StringBuilderCache.GetStringAndRelease(stringBuilder);
}

跳过 StringBuilderCache类的使用(这是 .NET 本身性能改进的一个很好的例子)我有一个问题:

为什么是

    if (this.Key != null)
{
StringBuilder arg_33_0 = stringBuilder;
TKey tKey = this.Key;
arg_33_0.Append(tKey.ToString());
}

更好

    if(this.Key != null)
{
stringBuilder.Append(this.Key.ToString());
}

?

分配新的局部变量而不是直接使用实例有什么好处?

最佳答案

根据 Reference Source 的原始 C# 代码是:

public override string ToString() { 
StringBuilder s = StringBuilderCache.Acquire();
s.Append('[');
if( Key != null) {
s.Append(Key.ToString());
}
s.Append(", ");
if( Value != null) {
s.Append(Value.ToString());
}
s.Append(']');
return StringBuilderCache.GetStringAndRelease(s);
}

根据 ILspy 的方法的 IL 代码是:

.method public hidebysig virtual 
instance string ToString () cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x5f79c
// Code size 125 (0x7d)
.maxstack 2
.locals init (
[0] class System.Text.StringBuilder,
[1] !TKey,
[2] !TValue
)

IL_0000: ldc.i4.s 16
IL_0002: call class System.Text.StringBuilder System.Text.StringBuilderCache::Acquire(int32)
IL_0007: stloc.0
IL_0008: ldloc.0
IL_0009: ldc.i4.s 91
IL_000b: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(char)
IL_0010: pop
IL_0011: ldarg.0
IL_0012: call instance !0 valuetype System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>::get_Key()
IL_0017: box !TKey
IL_001c: brfalse.s IL_0039

IL_001e: ldloc.0
IL_001f: ldarg.0
IL_0020: call instance !0 valuetype System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>::get_Key()
IL_0025: stloc.1
IL_0026: ldloca.s 1
IL_0028: constrained. !TKey
IL_002e: callvirt instance string System.Object::ToString()
IL_0033: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(string)
IL_0038: pop

IL_0039: ldloc.0
IL_003a: ldstr ", "
IL_003f: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(string)
IL_0044: pop
IL_0045: ldarg.0
IL_0046: call instance !1 valuetype System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>::get_Value()
IL_004b: box !TValue
IL_0050: brfalse.s IL_006d

IL_0052: ldloc.0
IL_0053: ldarg.0
IL_0054: call instance !1 valuetype System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>::get_Value()
IL_0059: stloc.2
IL_005a: ldloca.s 2
IL_005c: constrained. !TValue
IL_0062: callvirt instance string System.Object::ToString()
IL_0067: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(string)
IL_006c: pop

IL_006d: ldloc.0
IL_006e: ldc.i4.s 93
IL_0070: callvirt instance class System.Text.StringBuilder System.Text.StringBuilder::Append(char)
IL_0075: pop
IL_0076: ldloc.0
IL_0077: call string System.Text.StringBuilderCache::GetStringAndRelease(class System.Text.StringBuilder)
IL_007c: ret
} // end of method KeyValuePair`2::ToString

如您所见,只有一个 StringBuilder 类型的局部变量。

变量 arg_33_0arg_67_0 是您使用的反编译器的产物;它们既不在原始 C# 代码中,也不在编译后的 IL 代码中。

关于c# - KeyValuePair<TKey, TValue>.ToString 实现细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18172596/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com