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
相关产品推荐
相关产品推荐

