【问题标题】:Why can't a C# structure return a reference to its member field?为什么 C# 结构不能返回对其成员字段的引用?
【发布时间】:2018-03-30 11:27:11
【问题描述】:
struct Foo {
    int i;
    public ref int I => ref i;
}

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

【问题讨论】:

  • 由于值类型(结构)是在堆栈上分配的,一旦变量超出范围,为其成员之一返回的引用将变为无效,因此此错误对代码安全有意义。
  • @BradleySmith - 请停止重复这种疲惫且通常不正确的陈述。结构有时在堆栈上分配。有很多次他们不是。
  • 当然,它们可能被分配在堆栈上的事实足以解释编译器错误,虽然?
  • 真正理解 ref 返回限制需要理解指针。指针是危险的,一种赋予它们不受限制的能力的语言的标准编程错误是使用不再寻址有效内存位置的指针。 C# 不是这样的语言,编译器强制执行确保此类错误永远不会蔓延的语法。另一个要求是它需要确保垃圾收集器可以正确发现指针指向的内容,这是更大的问题sn-p。 en.wikipedia.org/wiki/Dangling_pointer

标签: c#


【解决方案1】:

我想我找到了解决办法:

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;
    }
}

这不是一个好主意 - 太多可怕的警告。但是,我确实相信它通过返回对结构成员的引用来实现您想要的,然后您可以对其进行编组以获取原始值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 2020-08-08
    相关资源
    最近更新 更多