我有:
结构
struct Data { int a; int b; }
包含结构
的类class Packet {
Data DataStruct;
}
当我现在实例化我的类时,我假设结构存在于堆上。 如果我现在做的事情
SomeClass.Process(new Packet().DataStruct);
SomeClass.Process(new Packet().DataStruct.a);
它会作为值传递吗?
如果没有,是否有任何理由不将结构化为类?
答案 0 :(得分:3)
struct
是值类型,因此它将作为value
传递。 Classes
是reference
种类型。
除非指定value
或out
,否则所有内容都将以ref
传递。
答案 1 :(得分:1)
结构总是按值传递。换句话说,它的副本被创建并提供给被调用的函数。
虽然结构是在堆上分配的,但它实际上是包含它的类的一部分,而不是作为一个单独的实体。
答案 2 :(得分:1)
结构实例存在于堆或堆栈上的事实根本不相关。很高兴知道它将在微软的CLR实现上存在,但这就是它。这只是一个实现细节。
值类型(结构)总是具有值语义。这与它们传递值是不同的,因为即使没有方法调用它也是相关的:
struct Data { public int a; public int b; } // Don't do this at home
var x = new Data { a = 1, b = 42 }; // x.a == 1, x.b == 42
var y = x; // x.a == 1, x.b == 42, y.a == 1, y.b == 42
y.a = 2; // x.a == 1, y.a == 2
var z = y; // x.a == 1, y.a == 2, z.a == 2
z.a = 3; // x.a == 1, y.a == 2, z.a == 3
// All variables hold a different copy of the struct
Debug.Assert(x.a == 1);
Debug.Assert(y.a == 2);
Debug.Assert(z.a == 3);
Debug.Assert(x.b == 42);
Debug.Assert(y.b == 42);
Debug.Assert(z.b == 42);
(这个事实使得拥有像上面那样的可变结构通常是一个坏主意。我只是出于演示目的使用它。不要在实际代码上执行。保持您的值类型不可变。)
如果你有一个参考类型,你会有不同的图片:
class Data { public int a; }
var x = new Data { a = 1 }; // x.a == 1
var y = x; // x.a == 1, y.a == 1
y.a = 2; // x.a == 2, y.a == 2
var z = y; // x.a == 2, y.a == 2, z.a == 2
z.a = 3; // x.a == 3, y.a == 3, z.a == 3
// All variables hold a reference to the same object:
Debug.Assert(x.a == 3);
Debug.Assert(y.a == 3);
Debug.Assert(z.a == 3);