Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 引用变量,而不是对象_C#_Reference_Variable Assignment - Fatal编程技术网

C# 引用变量,而不是对象

C# 引用变量,而不是对象,c#,reference,variable-assignment,C#,Reference,Variable Assignment,我想知道我是否可以做一个引用,它总是指向那个特定的变量,而不是该变量当前表示的对象(或者更准确地说是内存位置) 例如,假设我有以下程序,我想创建一个对MyClass a的引用,以便它始终返回MyClass a中的任何值,即使该值发生变化。我有一些代码看起来像 class MyClass { public int value = 0; } class Program { static MyClass saved; //maintained and used by the foll

我想知道我是否可以做一个引用,它总是指向那个特定的变量,而不是该变量当前表示的对象(或者更准确地说是内存位置)

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

您可以检查
保存的
是否已经有值:

static void StoreReference(MyClass input)
{
    if (saved != null) {
        return;
    }
    saved = input;
}

我在这里看到相当多的回复建议使用
readonly
字段或
ref
参数,但我不确定我是否完全理解这些相关的原因。如果我不明白你的问题,请原谅

但在我看来,你想否定赋值的效果(
a=b;
),这是不可能的

唯一的替代方法是在对
控制台的调用中切换到使用
保存的
而不是
a
。写入

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
,但是
只读
:这是一个非常合理的字段修改器,但是它:

  • 仅适用于字段,这意味着它将保护
    已保存的
    ,但不会保护局部变量
  • 只允许在构造函数中设置值,而不是在此处设置值
  • 所以,如果你真的打算使用它,不要误会我,它的功能很好,一定要小心这两个事实。你需要重新设计一下架构。老实说,我要避免在
    静态void Main(…)
    中出现这种情况——构造函数的废话可能会让人困惑

    无论如何,我想你可能是在试图解决一个本来就不应该存在的问题。这可能有助于了解这方面的实际用例,但从您给我们的信息来看,这似乎不是可能的,不幸的是,这是有充分理由的



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

    您可以将其定义为ReadOnlyId您尝试执行StoreReference(ref MyClass input)readonly的问题是,我想说a.value=42,而不是a=new MyClass(),第二个例子改变了a指向的内存位置。这有实际的使用案例吗?如果希望
    a
    不更改,为什么要坚持为其指定新值?只读变量只会阻止您编写
    a=new MyClass()
    ,而不会阻止您编写
    a.value=42