You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中是否支持传递对象指针的引用而非对象本身?

在C#中追踪引用变量的变更方案

在C#里,确实有几种方式可以实现追踪变量引用的变更(而非仅存储当前指向的对象),除了你提到的包装类方案,以下是几种可行的实现方式:

方案1:利用ref关键字结合委托捕获变量引用

C#不允许直接将ref类型作为类字段,但可以通过返回ref的委托间接捕获对变量的引用,每次访问时获取最新值:

public class TestValueClass
{
    public string AValue { get; set; }
}

public class TestPointerUsage
{
    private readonly Func<ref TestValueClass> _getLatestReference;

    public TestPointerUsage(Func<ref TestValueClass> getLatestReference)
    {
        _getLatestReference = getLatestReference;
    }

    public TestValueClass TestValueClass => _getLatestReference();
}

// 调用示例
var reference1 = new TestValueClass() { AValue = "reference1" };
TestValueClass myPointer = null;
var useClass = new TestPointerUsage(() => ref myPointer);
myPointer = reference1;
Console.WriteLine(useClass.TestValueClass.AValue); // 输出 "reference1"

此方案完全基于安全代码,无需特殊编译选项,且能保证每次访问都获取变量的最新引用。

方案2:启用unsafe代码直接操作指针

如果项目允许启用unsafe编译选项,可以直接存储变量的地址,从而追踪其引用变更:

public class TestValueClass
{
    public string AValue { get; set; }
}

public unsafe class TestPointerUsage
{
    private TestValueClass** _variableAddress;

    public TestPointerUsage(ref TestValueClass pointer)
    {
        fixed (TestValueClass** ptr = &pointer)
        {
            _variableAddress = ptr;
        }
    }

    public TestValueClass TestValueClass => **_variableAddress;
}

// 调用示例(需在项目属性中启用"允许不安全代码")
var reference1 = new TestValueClass() { AValue = "reference1" };
TestValueClass myPointer = null;
var useClass = new TestPointerUsage(ref myPointer);
myPointer = reference1;
Console.WriteLine(useClass.TestValueClass.AValue); // 输出 "reference1"

注意:unsafe代码会跳过CLR的部分安全检查,需确保被引用变量的生命周期长于TestPointerUsage实例,避免出现野指针问题。

方案3:使用Unsafe类在安全代码中操作引用地址

通过System.Runtime.CompilerServices.Unsafe类,可以在不启用unsafe的情况下操作引用的内存地址,实现类似指针的效果:

using System.Runtime.CompilerServices;

public class TestValueClass
{
    public string AValue { get; set; }
}

public class TestPointerUsage
{
    private readonly IntPtr _variableAddress;

    public TestPointerUsage(ref TestValueClass pointer)
    {
        _variableAddress = Unsafe.AsPointer(ref pointer);
    }

    public TestValueClass TestValueClass => Unsafe.AsRef<TestValueClass>(_variableAddress);
}

// 调用示例
var reference1 = new TestValueClass() { AValue = "reference1" };
TestValueClass myPointer = null;
var useClass = new TestPointerUsage(ref myPointer);
myPointer = reference1;
Console.WriteLine(useClass.TestValueClass.AValue); // 输出 "reference1"

此方案无需启用unsafe,但同样要注意变量的生命周期,避免变量被GC回收或内存移动导致地址失效。

内容的提问来源于stack exchange,提问作者DangerSchwob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:42:38