为什么我可以在c#7.3中将ref结构声明为类的成员?

为什么我可以在c#7.3中将ref结构声明为类的成员?,c#,.net,struct,c#-7.3,ref-struct,C#,.net,Struct,C# 7.3,Ref Struct,根据: 不能将ref结构声明为类或普通结构的成员 但我成功地编译并运行了这个: public ref struct RefStruct { public int value; } public class MyClass { public RefStruct Item => default; } ... MyClass c = new MyClass(); Console.WriteLine(c.Item.value); 现在,RefStruct是

根据:

不能将ref结构声明为类或普通结构的成员

但我成功地编译并运行了这个:

public ref struct RefStruct
{
    public int value;
}
public class MyClass
{
    public RefStruct Item => default;
}    
...       

MyClass c = new MyClass();
Console.WriteLine(c.Item.value);
现在,
RefStruct
是一个
RefStruct
,它是一个类的成员。 这种说法在某些情况下是错误的吗

更新
现在,文档已更新为更精确的描述。

它不是类的字段,而是属性getter的返回值,这很好,因为它只是函数返回值

请注意,“作为类的成员”通常包括属性,可能应该更改为“类的字段”

如果您试图将其声明为类字段(直接或通过自动实现的属性间接声明),则需要在堆栈上分配部分类(ref struct的数据),其余部分在管理堆中分配


问题中的代码定义了非自动实现属性。因此,编译器不需要在类中自动创建属性类型的隐藏字段。因此,虽然属性结果类型是
ref-struct
,但它实际上并不存储在类中,因此不违反任何类中都不包含该
ref-struct
类型的要求。请注意,即使创建setter方法本身也没问题-存储该属性的值将很棘手,但您可以安全地存储
ref结构的内容(
public int value;
,如本文所述)在
set
中,并在
get
中重新创建它

尝试更改
c.Item
中的值,您将看到您对声明的实际操作:)将行更改为
public RefStruct Item{get;set;}=default编译吗?有什么区别?公共RefStruct Item2(){returnnew RefStruct();}
呢?您的代码与前者更相似还是后者更相似?文档不正确——或者至少措辞不准确。编译器错误更准确-
字段或自动实现的属性不能是“Program.RefStruct”类型,除非它是ref struct的实例成员。
。这里的关键原则是编译器强制对象位于堆栈上。它不允许任何导致对象存在于堆上的行为(无论是字段还是字段支持的属性)。我将在页面上为您留下反馈。错误的哪一部分令人困惑?这意味着不能有一个字段(无论是显式字段还是自动属性后面的隐式字段)是ref结构。如果你想这样做,答案是你不能;P
那么您可以在setter中执行什么操作?
您想要的任何操作(例如
新建
在ref结构上,写入控制台等)。只要没有作为ref结构的显式或隐式字段。您能想到的任何情况都会100%地被该错误消息覆盖。它的措辞非常准确(与文档不同)。@SeM如我所说-文档不正确/不精确。我给他指出了一个更好的信息来源,错误信息本身。我给他们留下了修改文档的反馈。我试图解释编译器正在执行的原则。我不知道还能说些什么。你不能创建
ref-struct
的属性,编译器会给出一个错误:“字段或自动实现的属性不能是'RefStruct'类型,除非它是ref-struct的实例成员。”是的,我明白了,我认为文档需要一些改进@sᴇM我认为您需要设置getter,而不是使用自动设置。@joe确定如果您只创建一个getter返回默认值的属性,它将与您声明的相同。例如:
public RefStruct MyProperty{get{return default;}}
,它相当于
RefStruct MyMethod()=>default@SᴇM我想我已经对你的评论加了解释——看看这是否足够。