参考变量,不参考

时间:2015-06-14 21:18:15

标签: c# reference variable-assignment

我想如果我可以创建一个始终指向该特定变量的引用,而不是该变量当前所代表的对象(或更准确的内存位置)。

作为一个例子,假设我有以下程序,我想创建一个对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处返回错误)?

2 个答案:

答案 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:这是一个非常合理的修饰符,可以放在你的领域,

  1. 仅适用于字段,这意味着它将保护saved,但不保护本地变量。
  2. 只允许在构造函数中设置值,而不是在此处尝试设置值。
  3. 因此,如果你打算使用它,并且不要误解我的意思,那就是它的作用,请注意这两个事实。你需要一些重新架构。老实说,我会在static void Main(...)中避免这种情况 - 构造函数的废话可能会让人感到困惑。

    无论如何,我认为你可能正试图解决一个不应该存在的问题。看到一个真实世界的用例可能会有所帮助,但是从你给我们的内容来看,这听起来并不是一件可能的事情,不幸的是有充分的理由。

    对于它的价值,你的标题和开头段落让我觉得你正在寻找指向指针的指针,这在管理的C#中是不允许的。我从来没有冒险进入非托管C#,但它在C ++中是允许的,所以我怀疑它可能会得到支持。无论如何,你的其余部分并没有真正提醒我,所以这可能不相关。