值类型字段是引用类型?

问题描述:

我在这里有点困惑。使用结构体时,我不能直接更改其字段,因为整个结构体都是值类型的。 但是值类型字段的类呢?如果我有一个公共字段int X,我可以正确修改它。因此,其领域的价值型性质的唯一表现就是,当作为一个论点获得通过时,它是一个副本?值类型字段是引用类型?

编辑:另外

Class A 
{ 
    int B=100; //this is a field, so reference type. But it is a value type. 
} 

的地址B的内容被存储在堆上,但被存储在堆栈中B的值?

+2

问题不是100%清楚。你能提供代码示例,以便我们更好地理解? – peval27

+0

是什么让你认为所有的字段都是引用类型? – Servy

有了结构,我不能直接改变它的字段,因为整个结构都是值类型的。

当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 s,只要你修改它的全部。你不能修改int的一部分,因为它不是一个组合。当您一次分配整个struct时,struct的修改可以正常工作。换句话说,分配

b.F = new Foo { A = 112233 }; 
在我的例子

替换你的榜样分配

B = 100; 

Demo.

结构为您提供了原始字段的副本,因为结构的副本将被传递。将其更改为类将传递该类的引用,因此如果要更改该字段,则该字段将进行修改。

B的内容地址存储在堆中,但是存储在堆栈中的B的值是多少?

否。类的值类型字段存储在堆中。

请参考@Marc Gravell的答案在这里,了解更多有关这一点:

Why value-types are stored onto Stacks?

你也可以阅读关于这个问题@Eric Lippert的博客文章:https://blogs.msdn.microsoft.com/ericlippert/2010/09/30/the-truth-about-value-types/

总之值类型可以将存储在堆栈上,但它们并不总是存储在堆栈上。