我想如果我可以创建一个始终指向该特定变量的引用,而不是该变量当前所代表的对象(或更准确的内存位置)。
作为一个例子,假设我有以下程序,我想创建一个对MyClass a的引用,以便它始终返回MyClass a中的任何值,即使该值发生变化。我有一些看起来像的代码。
class MyClass
{
public int value = 0;
}
class Program
{
static MyClass saved; //maintained and used by the following two functions
static void StoreReference(MyClass input)
{
saved = input;
}
static void SetValue()
{
saved.value = 42;
}
static void Main(string[] args)
{
//A couple arbitrary classes I'd like to have references to
MyClass a = new MyClass();
MyClass b = new MyClass();
StoreReference(a);
a = b;
SetValue();
Console.Write(a.value); //should print 42, instead prints 0 since it reads in the original object a was set to
}
}
是否有任何可以在C#中执行此操作的内容,或者任何可以阻止将变量分配到新内存位置的内容(以便上面的代码在a = b处返回错误)?
答案 0 :(得分:0)
您可以检查saved
是否已有值:
static void StoreReference(MyClass input)
{
if (saved != null) {
return;
}
saved = input;
}
答案 1 :(得分:0)
我在这里看到很多回复建议使用readonly
字段或ref
参数,但我不确定我是否完全理解为什么这些参数是相关的。如果我不明白你的问题,请原谅。
但是从我看到的情况来看,你希望否定作业(a = b;
)的效果,这是不可能的。
唯一的替代方法是在调用saved
a
代替Console.Write
static void Main(string[] args)
{
MyClass a = new MyClass();
MyClass b = new MyClass();
StoreReference(a);
a = b;
SetValue();
Console.Write(saved.value);
}
将工作,它将按照您的需要打印42。但我明白这不是你想要的。
但是,没有语言功能可以让代码编译和让你做你想做的事。这是一件好事。这就是编译器运行这些检查(或者其中的一部分,无论如何)的原因。如果你忘了你有这个虚构的修饰符来使局部变量只读,并且你写出了任务,期望它像任何C语言中的其他地方一样工作,那将是非常令人困惑的。
现在,对于其他人一直在说的话,我真的不确定为什么ref
已经出现了,但readonly
:这是一个非常合理的修饰符,可以放在你的领域, 但:
saved
,但不保护本地变量。因此,如果你打算使用它,并且不要误解我的意思,那就是它的作用,请注意这两个事实。你需要一些重新架构。老实说,我会在static void Main(...)
中避免这种情况 - 构造函数的废话可能会让人感到困惑。
无论如何,我认为你可能正试图解决一个不应该存在的问题。看到一个真实世界的用例可能会有所帮助,但是从你给我们的内容来看,这听起来并不是一件可能的事情,不幸的是有充分的理由。
对于它的价值,你的标题和开头段落让我觉得你正在寻找指向指针的指针,这在管理的C#中是不允许的。我从来没有冒险进入非托管C#,但它在C ++中是允许的,所以我怀疑它可能会得到支持。无论如何,你的其余部分并没有真正提醒我,所以这可能不相关。