C#类中的引用域field
在C#面向程序设计中,我们可能有这样的需求,想达到C++中指针的效果,在类中设置一个指针(引用)变量指向某个域,然后通过这个指针(引用)来更改它。
很遗憾,C#中并不允许类的field成员是ref的,理由如下:
假设我们允许类的成员是ref的,就会有下面这样子的代码,
public ref int x;
void M()
{
int y = 123;
this.x = ref y;
}
看起来似乎没什么问题,通过this.x
可以如期的访问到y,更改他的值。然而这背后隐藏着巨大的危险。当本函数的运行期结束后,栈空间被回收,x就指向了被回收的栈空间中的某处,这是非常危险的。
但我们可以通过封装一个类,来达到类似的效果
sealed class Ref<T>
{
private readonly Func<T> getter;
private readonly Action<T> setter;
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value { get { return getter(); } set { setter(value); } }
}
...
Ref<int> x;
void M()
{
int y = 123;
x = new Ref<int>(()=>y, z=>{y=z;});
x.Value = 456;
Console.WriteLine(y); // 456 -- setting x.Value changes y.
}
Ref类通过get和set两个匿名函数,间接的访问到了被引用变量。当被引用变量生存期过了,死亡了,再对引用变量进行set和get则会抛出异常。