假设我们有以下只读记录 struct 定义
public readonly record struct S(int A, int B)
{
}
由于在记录中位置参数将自动实现为属性,因此A
和B
将导致防御副本.
我们可以通过这样修改定义来避免它
public readonly record struct S(int A, int B)
{
public readonly int A = A;
public readonly int B = B;
}
在这种情况下,A
和B
是字段,因此对访问没有副作用,因此没有防御性拷贝.根据我的测试和对这两个定义的理解,编译器会合成相同的记录特定代码(Equity、HashCode生成等).
我想知道是否有更好的方法来避免带有记录的防御性副本.所有只读字段的定义可能很麻烦,而且可能容易出错.是否有任何C#语言来实现我在这里的目标,或者只读字段是我能做的最好的?
另外,如果我对本例中的防御性副本和记录代码合成的理解是错误的,请解释我没有正确理解的地方.
编辑:
衡量标准:
const int SIZE = 10000;
var sw = new Stopwatch();
A[] aArray = new A[SIZE];
M[] mArray = new M[SIZE];
for(int repeat = 0; repeat < SIZE; repeat++) aArray[repeat] = new A(new(new(new(new(new(new(new(new(new(new(new(Random.Shared.Next()))))))))))));
for(int repeat = 0; repeat < SIZE; repeat++) mArray[repeat] = new M(new(Random.Shared.Next()));
int i = 0;
sw.Start();
for(int repeat = 0; repeat < SIZE; repeat++) i =+ aArray[repeat].B.C.D.E.F.G.H.I.J.K.L.I;
sw.Stop();
System.Console.WriteLine(i);
System.Console.WriteLine(sw.Elapsed);
sw.Reset();
sw.Start();
for(int repeat = 0; repeat < SIZE; repeat++) i =+ mArray[repeat].N.I;
sw.Stop();
System.Console.WriteLine(i);
System.Console.WriteLine(sw.Elapsed);
readonly record struct A(B B){public readonly B B = B;}
readonly record struct B(C C){public readonly C C = C;}
readonly record struct C(D D){public readonly D D = D;}
readonly record struct D(E E){public readonly E E = E;}
readonly record struct E(F F){public readonly F F = F;}
readonly record struct F(G G){public readonly G G = G;}
readonly record struct G(H H){public readonly H H = H;}
readonly record struct H(I I){public readonly I I = I;}
readonly record struct I(J J){public readonly J J = J;}
readonly record struct J(K K){public readonly K K = K;}
readonly record struct K(L L){public readonly L L = L;}
readonly record struct L(int I){public readonly int I = I;}
readonly record struct M(N N){public readonly N N = N;}
readonly record struct N(int I){public readonly int I = I;}
readonly record struct A(B B){}
readonly record struct B(C C){}
readonly record struct C(D D){}
readonly record struct D(E E){}
readonly record struct E(F F){}
readonly record struct F(G G){}
readonly record struct G(H H){}
readonly record struct H(I I){}
readonly record struct I(J J){}
readonly record struct J(K K){}
readonly record struct K(L L){}
readonly record struct L(int I){}
readonly record struct M(N N){}
readonly record struct N(int I){}
我不知道发生了什么,但我知道我重做了测量,在两种情况下得到了相似的值.
要运行它,只需注释掉其他定义.我在 struct 体中嵌套这么多 struct 体的原因是,我想确保在另一个 struct 体的字段中访问一个 struct 体的字段不会产生副本.
我很抱歉给您造成了混乱.显然我第一次就做错了什么.在这两种情况下都不应该有任何防御性的副本.