C# 值类型字段是否为引用类型?

C# 值类型字段是否为引用类型?,c#,stack,value-type,C#,Stack,Value Type,我在这里有点困惑。对于structs,我不能直接更改它的字段,因为整个struct都是值类型。 但是有值类型字段的类呢?如果我有一个公共字段intx,我可以正确地修改它。所以,它的字段的值类型性质的唯一表现是,当作为参数传递时,它是一个副本 编辑:也 Class A { int B=100; //this is a field, so reference type. But it is a value type. } 内容B的地址存储在堆上,但B的值是否存储在堆栈上 对于structs,

我在这里有点困惑。对于structs,我不能直接更改它的字段,因为整个struct都是值类型。 但是有值类型字段的类呢?如果我有一个公共字段intx,我可以正确地修改它。所以,它的字段的值类型性质的唯一表现是,当作为参数传递时,它是一个副本

编辑:也

Class A
{
  int B=100;  //this is a field, so reference type. But it is a value type.
}
内容B的地址存储在堆上,但B的值是否存储在堆栈上

对于structs,我不能直接更改它的字段,因为整个struct都是值类型

当C#为您复制
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);
}
如果我有一个公共字段
intx
,我可以正确地修改它

同样的规则也适用于用户定义的
struct
s,只要您修改整个结构即可。不能修改
int
的一部分,因为它不是一个组合。当您一次分配整个
struct
时,对
struct
的修改工作正常。换句话说,分配

b.F = new Foo { A = 112233 };
B = 100;
在我的例子中,替换赋值

b.F = new Foo { A = 112233 };
B = 100;
在你的例子中


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

内容B的地址存储在堆上,但B的值是否存储在堆栈上

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

有关这方面的更多信息,请参考@Marc Gravell的回答:

您可能还想阅读@Eric Lippert关于该主题的博客文章:


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

问题并非100%清楚。您能提供代码示例以便我们更好地理解吗?是什么让您认为所有字段都是引用类型?