为什么可以';C#结构是否返回对其成员字段的引用?

为什么可以';C#结构是否返回对其成员字段的引用?,c#,C#,这段代码会引发编译错误CS8170,但如果Foo是一个类,则不会。为什么结构不能返回成员作为引用?我想我找到了解决方法: struct Foo { int i; public ref int I => ref i; } 这并不是一个好主意——有太多可怕的警告。但是,我相信,通过返回对结构成员的引用,可以实现您想要的功能,然后可以封送以获取原始值。由于值类型(结构)是在堆栈上分配的,因此为其中一个成员返回的引用将在变量超出范围后立即失效,因此,这个错误对于代码安全是有意义的

这段代码会引发编译错误CS8170,但如果
Foo
是一个类,则不会。为什么结构不能返回成员作为引用?

我想我找到了解决方法:

struct Foo {
    int i;
    public ref int I => ref i;
}

这并不是一个好主意——有太多可怕的警告。但是,我相信,通过返回对结构成员的引用,可以实现您想要的功能,然后可以封送以获取原始值。

由于值类型(结构)是在堆栈上分配的,因此为其中一个成员返回的引用将在变量超出范围后立即失效,因此,这个错误对于代码安全是有意义的。@BradleySmith-请停止重复这个令人厌倦且通常不正确的语句。有时会在堆栈上分配结构。有很多时候它们不是。当然,它们可能被分配到堆栈上这一事实足以解释编译器错误,但是?真正摸索ref返回限制需要理解指针。指针是危险的,在一种语言中,一个标准的编程错误是使用一个不再寻址有效内存位置的指针,而这种语言赋予了指针不受限制的能力。C#不是这样一种语言,编译器强制执行语法,确保这样的错误永远不会潜入。另外一个要求是,它需要确保垃圾收集器能够正确地发现指针指向的是什么,这是这个代码段中更大的问题。这里还有一些附加说明:
class Program
{
    static void Main(string[] args)
    {
        Foo temp = new Foo(99);
        Console.WriteLine($"{Marshal.ReadInt32(temp.I)}");
        Console.ReadLine();
    }
}
struct Foo
{
    int i;
    public IntPtr I;

    public Foo(int newInt)
    {
        i = newInt;
        I = GetByRef(i);
    }
    static unsafe private IntPtr GetByRef(int myI)
    {
        TypedReference tr = __makeref(myI);
        int* temp = &myI;
        IntPtr ptr = (IntPtr)temp;
        return ptr;
    }
}