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