Dre*_*kes 14 .net c# optimization c#-7.2 in-parameters
C#7.2引入了in
修饰符,用于通过引用传递参数,并保证接收者不会修改参数.
这篇文章说:
你永远不应该使用非readonly结构作为in参数,因为它可能会对性能产生负面影响,如果结构是可变的,可能会导致模糊的行为
这是什么意思为内置原语,例如int
,double
?
我想in
用来表达代码中的意图,但不是以防御性副本的性能损失为代价.
问题
in
参数传递原始类型并且没有制作防御性副本是否安全?DateTime
,TimeSpan
,Guid
,...考虑readonly
由JIT?
快速测试显示,目前,是的,为内置基元类型和结构创建了防御性副本.
使用VS 2017(.NET 4.5.2,C#7.2,发布版本)编译以下代码:
using System;
class MyClass
{
public readonly struct Immutable { public readonly int I; public void SomeMethod() { } }
public struct Mutable { public int I; public void SomeMethod() { } }
public void Test(Immutable immutable, Mutable mutable, int i, DateTime dateTime)
{
InImmutable(immutable);
InMutable(mutable);
InInt32(i);
InDateTime(dateTime);
}
void InImmutable(in Immutable x) { x.SomeMethod(); }
void InMutable(in Mutable x) { x.SomeMethod(); }
void InInt32(in int x) { x.ToString(); }
void InDateTime(in DateTime x) { x.ToString(); }
public static void Main(string[] args) { }
}
Run Code Online (Sandbox Code Playgroud)
使用ILSpy反编译时产生以下结果:
...
private void InImmutable([System.Runtime.CompilerServices.IsReadOnly] [In] ref MyClass.Immutable x)
{
x.SomeMethod();
}
private void InMutable([System.Runtime.CompilerServices.IsReadOnly] [In] ref MyClass.Mutable x)
{
MyClass.Mutable mutable = x;
mutable.SomeMethod();
}
private void InInt32([System.Runtime.CompilerServices.IsReadOnly] [In] ref int x)
{
int num = x;
num.ToString();
}
private void InDateTime([System.Runtime.CompilerServices.IsReadOnly] [In] ref DateTime x)
{
DateTime dateTime = x;
dateTime.ToString();
}
...
Run Code Online (Sandbox Code Playgroud)
(或者,如果你喜欢IL :)
IL_0000: ldarg.1
IL_0001: ldobj [mscorlib]System.DateTime
IL_0006: stloc.0
IL_0007: ldloca.s 0
IL_0009: call instance string [mscorlib]System.DateTime::ToString()
IL_000e: pop
IL_000f: ret
Run Code Online (Sandbox Code Playgroud)