类中的结构是否作为值传递?

时间:2011-02-16 10:03:14

标签: c# .net

我有:

结构

struct Data { int a; int b; }

包含结构

的类
class Packet {
    Data DataStruct;
}

当我现在实例化我的类时,我假设结构存在于堆上。 如果我现在做的事情

SomeClass.Process(new Packet().DataStruct);
SomeClass.Process(new Packet().DataStruct.a);

它会作为值传递吗?

如果没有,是否有任何理由不将结构化为类?

3 个答案:

答案 0 :(得分:3)

struct是值类型,因此它将作为value传递。 Classesreference种类型。

除非指定valueout,否则所有内容都将以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);