我在这里有点困惑。对于结构,我不能直接更改其字段,因为整个结构都是值类型。但是,具有值类型字段的类呢?如果我有一个公共字段 int X,我可以正确修改它。因此,其字段的值类型性质的唯一表现是,当作为参数传递时,它是一个副本?
编辑:也
Class A
{
int B=100; //this is a field, so reference type. But it is a value type.
}
B 的内容地址存储在堆上,但 B 的值是否存储在堆栈上?
对于结构,我不能直接更改其字段,因为整个结构都是值类型。
在 C# 为您创建struct
副本的情况下,您无法更改字段。在其他情况下,您可以修改struct
的字段。以下是差异的一个小演示:
struct Foo {
public int A {get;set;}
public void SetA(int a) {
A = a;
}
}
class Bar {
Foo f;
public Foo F {
get{return f;}
set {f = value;}
}
public void SetFooA(int x) {
f.SetA(x);
}
}
public static void Main() {
Bar b = new Bar();
b.F.SetA(123); // b.F makes a copy, so changing A fails
Console.WriteLine("{0}", b.F.A);
b.SetFooA(456); // Inside Bar, f.SetA is called directly, so the change works fine
Console.WriteLine("{0}", b.F.A);
b.F = new Foo { A = 112233 }; // This also works, because the whole F is assigned
Console.WriteLine("{0}", b.F.A);
}
如果我有一个公共字段
int X
,我可以正确修改它。
相同的规则适用于用户定义的struct
,只要您修改整个规则即可。你不能修改int
的一部分,因为它不是复合的。一次分配整个struct
时,修改struct
可以正常工作。换句话说,分配
b.F = new Foo { A = 112233 };
在我的示例中替换分配
B = 100;
在您的示例中。
演示。
B的内容地址存储在堆上,但 B 的值是否存储在堆栈上?
不。类的值类型字段存储在堆中。
有关此内容的更多信息,请参阅@Marc Gravell的回答:
为什么值类型存储在堆栈上?
您可能还想阅读Lippert关于该主题@Eric博客文章:https://blogs.msdn.microsoft.com/ericlippert/2010/09/30/the-truth-about-value-types/
简而言之,值类型可以存储在堆栈中,但它们并不总是存储在堆栈中。
Struct 为您提供原始字段的副本,因为将传递该结构的副本。将其更改为类将传递对该类的引用,因此如果要更改该字段,该字段将修改。