Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类中的结构是否作为值传递?_C#_.net - Fatal编程技术网

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

C# 类中的结构是否作为值传递?,c#,.net,C#,.net,我有: 结构 struct Data { int a; int b; } 包含结构的类 class Packet { Data DataStruct; } 当我现在实例化我的类时,我假设结构存在于堆上。 如果我现在这样做 SomeClass.Process(new Packet().DataStruct); SomeClass.Process(new Packet().DataStruct.a); 它会作为值传递吗 如果不是,是否有理由不将结构改为类?structs是值类型,因此它

我有:

结构

struct Data { int a; int b; }
包含结构的类

class Packet {
    Data DataStruct;
}
当我现在实例化我的类时,我假设结构存在于堆上。 如果我现在这样做

SomeClass.Process(new Packet().DataStruct);
SomeClass.Process(new Packet().DataStruct.a);
它会作为值传递吗


如果不是,是否有理由不将结构改为类?

struct
s是值类型,因此它将作为值传递<代码>类是
参考
类型


除非指定了
out
ref
,否则所有内容都将作为
value
传递。

结构始终按值传递。换句话说,它的一个副本被创建并提供给被调用的函数


虽然结构是在堆上分配的,但它实际上是它所包含的类的一部分,而不是作为一个单独的实体。

结构的实例存在于堆或堆栈上这一事实根本不相关。很高兴知道它将存在于微软的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);

诀窍在于:忘记堆和堆栈。引用类型视为引用,值类型视为值。就是这样。类引用是按值传递的,除非它是
out
ref
,当引用按引用传递时。我明白了。所以,如果我有这样的东西:
c=newc();a=c
c
的引用被复制到
a
?而
b=newstruct();a=b
I实际上是复制数据本身。更准确地说,所有数据都是按值传递的,除非参数具有
ref
out
修饰符。(对于引用类型,引用也通过值传递)