可链接变量类型

hal*_*l12 3 c# variables ref

哪些变量类型可以链接?我试图使用对象,但它没有做我想要的.

object a;
object b;
b = 5;
a = b;
b = 2;
label1.Text = Convert.ToString(a);
Run Code Online (Sandbox Code Playgroud)

它写了5但我希望它是2.

jas*_*son 7

这是对引用及其工作原理以及变量的简单误解.

object a; // a is a storage location
          // it holds references to instances of object

object b; // b is a storage location
          //it holds references to instances of object

b = 5; // "boxes" 5 into an instance of object
       // and assigns reference to that object to b

a = b; // assigns reference in storage location b to storage location a

b = 2; // "boxes" 2 into an instance of object
       // and assign reference to that object to b
Run Code Online (Sandbox Code Playgroud)

想想这样.a并且b是一张纸张,上面有房子的地址.当你说b = 5,把它想象成5在纸上写下房子的地址b.当你说a = b,把它作为复制被写上的地址ba.当你说的时候b = 2,把它想象成擦除写在b上面的地址并用地址替换它2.此操作不会更改写在纸上的值a.这就是这里发生的事情.

现在,让我们看一个非常简单的方法来制作你想要做的工作.

class MyValue {
    public int Value { get; set; }
}

MyValue b = new MyValue { Value = 5 }; 
MyValue a = b;
b.Value = 2;
Run Code Online (Sandbox Code Playgroud)

现在,如果你说

Console.WriteLine(a.Value);
Run Code Online (Sandbox Code Playgroud)

会发生什么?让我们小心翼翼.再次,回到类比ab作为写在其上的地址的纸张.我们已经说过了MyValue b = new MyValue { Value = 5 }.想到这就是在纸上写下b地址到家里,5前面有一个标志牌.想想a = b作为复制被写上的地址ba.然后,考虑b.Value = 2改变前门上方标志的值,在这种情况下,改变52.现在,如果有人问,家里的门上面有什么价值,那里有写在纸上的地址a?嗯,地址与地址a相同b.我们只是改变了前门上的标识值52.所以,我们期待看到2.

试一试,尝试一下,你会看到2打印到控制台的值.

一遍又一遍地思考这个问题,直到你感觉到它深藏在你的骨头里.在你掌握这个基本概念之前,你会发现编程的理由非常具有挑战性.


Eri*_*ert 5

杰森的回答很好; 添加更多内容:

你似乎期望当你说a = b这意味着a并且b现在是同一个变量的别名时.这不是它的意思; a = b表示将存储位置的内容复制b到存储位置a,而不是重新标记存储位置a.

还有就是然而,一种方法,使两个变量互为别名; 事实上,在C#中有三种方法可以做到这一点(除了Jason建议的技术,这可能是最好的).

第一种方法是使用refout参数:

class P
{
    static object b = 5;
    static void M(ref object a) 
    { 
        b = 2;
        Console.WriteLine(a);
    }
    static void Main()
    {
        M(ref b);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你运行它,你会看到它做你想要的.b作为开始5,那么ref意味着ab成为别名.何时b更改为2,a也是因为它们是具有两个不同名称的相同变量.

但是在单个方法中无法做到这一点.底层运行时支持这一点,我曾经制作了一个支持的C#版本:

object b = 5;
ref object a = ref b;
b = 2;
// now a is 2
Run Code Online (Sandbox Code Playgroud)

但这从未使其成为发送给客户的语言版本.

将一个变量设为另一个变量的第二种方法仅适用于高级程序员; 你可以创建一个指针,当解引用别名变量时:

int b = 5;
int* a = &b;
b = 2;
// Now *a is 2
Run Code Online (Sandbox Code Playgroud)

请注意,指针类型只能对"非托管类型"的变量进行别名int,而不是像托管类型那样object.

我已经编写了十年的高级C#编程,并且从未在生产代码中执行此操作,所以如果我是你,我会避免使用它.

将一个变量设为另一个变量的第三种方法仅适用于高级程序员; 您可以使用TypedReferenceC#的类型和一些未记录的功能来捕获对变量的引用,然后再解除引用到别名.我的建议是不要使用此功能.

  • @ halil12:是的;*任何*变量都可以通过`ref`传递.数组元素是一个变量.你不能通过ref传递的一件事是*属性*; 具有getter和setter的属性实际上不是变量. (2认同)