可链接变量类型

时间:2013-06-01 13:45:34

标签: c# variables ref

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

object a;
object b;
b = 5;
a = b;
b = 2;
label1.Text = Convert.ToString(a);

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

3 个答案:

答案 0 :(得分: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

这样想。 ab是张纸,上面有住家的地址。当您说b = 5时,请将其视为在论文5上写下地址为b的地址。当您说a = b时,请将其视为复制b上写入a的地址。当您说b = 2时,请将其视为删除写在b上的地址,并将其替换为地址2此操作不会更改写在论文a上的值。这就是这里发生的事情。

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

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

MyValue b = new MyValue { Value = 5 }; 
MyValue a = b;
b.Value = 2;

现在,如果你说

Console.WriteLine(a.Value);

会发生什么?让我们小心翼翼。再次回到ab的类比,作为写有地址的纸条。我们已经说过MyValue b = new MyValue { Value = 5 }。可以把它想象成在纸上写下b地址到一个家,上面有一个标语5。将a = b视为复制b上写入a的地址。然后,将b.Value = 2视为更改前门上方标志的值,在这种情况下,将5更改为2。现在,如果有人问,家里门上的价值是什么,那里的地址写在纸上a?好吧,a上的地址与b上的地址相同。我们刚刚将前门上方标志的值从5更改为2。因此,我们希望看到2

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

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

答案 1 :(得分:5)

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

当您说a = b这意味着ab现在是同一个变量的别名时,您似乎期望。这不是它的意思; a = b表示将存储位置b内容复制到存储位置a,而不是 relabel 存储位置{{1} }。

然而 是一种让两个变量互为别名的方法;事实上,在C#中有三种方式(除了Jason建议的技术,这可能是最好的)。

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

out

如果你运行它,你会看到它做你想要的。 class P { static object b = 5; static void M(ref object a) { b = 2; Console.WriteLine(a); } static void Main() { M(ref b); } } b开头,5表示refa成为别名。当b更改为b时,2也是因为它们是具有两个不同名称的相同变量。

但是在单个方法中没有办法。底层运行时支持这一点,我曾经制作过支持的C#版本:

a

但这从未成为发给客户的语言版本。

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

object b = 5;
ref object a = ref b;
b = 2;
// now a is 2

请注意,指针类型只能对int b = 5; int* a = &b; b = 2; // Now *a is 2 之类的“非托管类型”变量进行别名,而不能像int那样使用托管类型

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

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

答案 2 :(得分:0)

using System;

class Program
{
    static void Main(string[] args)
    {
        ValueTypeWrapper<int> a;
        ValueTypeWrapper<int> b;

        // The following line creates a new instance
        // of ValueTypeWrapper<int> by the means of
        // implicit conversion (see last method defined
        // in the ValueTypeWrapper<T> class).
        b = 5;

        // Make the variable "a" point to the same
        // ValueTypeWrapper<int> instance we just created.
        a = b;

        // Now that both variables are pointing to
        // the same *instance*, change the value of
        // the Value property.
        b.Value = 2;

        // Convert.ToString(...) will call
        // ValueTypeWrapper<int>'s ToString()
        // method, which in turn produces the
        // string equivalent of the value inside
        // the Value property.
        // The Value property is equal to 2
        // on both "a" and "b" objects as they
        // point to the same instance.
        Console.WriteLine(Convert.ToString(a));
        Console.ReadLine();
    }
}

public class ValueTypeWrapper<T> where T : struct
{
    public T Value { get; set; }

    public override string ToString()
    {
        return this.Value.ToString();
    }

    public static implicit operator ValueTypeWrapper<T>(T value)
    {
        return new ValueTypeWrapper<T> { Value = value };
    }
}