Generic中的ref类型和值类型

时间:2009-07-07 05:30:07

标签: c# generics

我正在研究一种演示方法并发现一些奇怪的东西(至少对我来说: - ))

enter code here  class Program
{
    public void AnotherSwap<T>(T a, T b)  
    {
        T temp;
        temp = a;
        a = b;
        b = temp;

        Console.WriteLine(a);
        Console.WriteLine(b);

    }


    public void swap<T>(T a, T b) where T : MyInt  // Passing without ref
    {
        object temp;
        temp = a.MyProperty;
        a.MyProperty = b.MyProperty;
        b.MyProperty = (int)temp;

        Console.WriteLine(a.MyProperty);
        Console.WriteLine(b.MyProperty);



    }

    static void Main(string[] args)
    {
        Program p = new Program();
        MyInt a = new MyInt() { MyProperty = 10 };
        MyInt b = new MyInt() { MyProperty = 20 };
        p.swap<MyInt>(a, b);
        Console.WriteLine(a.MyProperty); // changed values get reflected
        Console.WriteLine(b.MyProperty); // changed values get reflected

        Console.WriteLine("Another Swap");
        object x = 10;
        object y = 20;
        p.AnotherSwap(x, y);

        Console.WriteLine(x);  // changed values are not getting  reflected
        Console.WriteLine(y);  // changed values are not getting  reflected

         Console.ReadKey();


    }
   public class MyInt
    {
        public int MyProperty { get; set; }

    }




}

这里当我调用swap()时,虽然我没有提到ref,但是更改后的值会自动反映出来(如p.swap(a,b); a和b是Myint的实例,因此会根据我的理解,默认情况下作为参考。) 但同样的情况应该发生在Anotherswap()这里我也传递对象x,y但现在这些值没有反映在Main().i.e中。现在它作为一种价值类型。 有人可以解释我的理解是错误的。 如果你们想要更多信息,请告诉我。

3 个答案:

答案 0 :(得分:3)

您的问题具有误导性,答案实际上比这简单:

在Swap函数中,您将交换这些类中的MyProperty属性的值,而不是实际的类本身。如果你在MyInt类中有另一个名为“Name”的属性,那么很容易证明这一点。在调用Swap之后,您会看到Name属性保持不变。

在AnotherSwap中没有发生任何有趣事情的原因是因为你根本没有通过ref传递类型,所以你对函数内对象指针执行的赋值不会修改原始对象的指针。来电者的观点。

要考虑的其他事情是,当你将10变成一个物体时,你实际上正在装箱,这是你需要记住的其他东西。在编写泛型时,您希望对于引用与值类型的行为不同,我总是只使用“where T:class”作为引用类型,使用“where T:struct”作为值类型。但这两个函数的名称不能相同。

答案 1 :(得分:1)

当MyInt类型被转换为Object时,它将被转换为val类型。对象不能像引用一样对待,因为它表示val和ref,它必须由ref。

显式传递

int可以作为对象进行转换,并且仍然将其视为val。 string可以作为对象进行转换,并将其视为val。即使通常它会是ref类型。

如果您使用了AnotherSwap并将T in作为MyInt传递,您将获得与以前相同的结果。如果使用对象调用原始交换算法,则会得到与后者相同的输出。

答案 2 :(得分:1)

第二组对象[object x = 1]被转换为int,这是一个值类型,因为它在初始化时被赋予了一个int,所以它被视为int这是一个值类型

如果您运行以下代码段,您会看到我的观点。

object test = 1;
Console.Writeline(test.GetType());

returns: "typeof (Int32)"

所以object的类型不再是对象,而是Int32,它是一种值类型。

object test = 1;
Console.Writeline(test.GetType().IsByRef);

returns: "false"