代码之家  ›  专栏  ›  技术社区  ›  user366312

对象/对象

  •  1
  • user366312  · 技术社区  · 15 年前

    C是 Object / object 值类型还是引用类型?

    我检查了它们是否可以保留引用,但这些引用不能用于更改对象。

    using System;
    
    class MyClass
    {
        public static void Swap(Object obj1, Object obj2)
        {
            Console.WriteLine("After Swapping");
            obj1 = 100;
            obj2 = 200;
        }
    }
    
    class MainClass 
    {
        static void Main(string[] args) 
        {
            Object obj1 = new Object ();
            obj1 = 10;
    
            Object obj2 = new Object ();
            obj2 = 20;
    
            Console.WriteLine(obj1.ToString());
            Console.WriteLine(obj2.ToString());
    
            MyClass.Swap(obj1, obj2);
    
            Console.WriteLine(obj1.ToString());
            Console.WriteLine(obj2.ToString());
    
            Console.ReadLine();
        }
    }
    
    6 回复  |  直到 15 年前
        1
  •  5
  •   Kobi    15 年前

    您所做的更改 Swap 仅限于此-您只玩指针(和拳击),函数外部的引用保持不变(您有4个引用)。如果更改方法的签名,您将看到不同之处:

    尝试 Swap(ref Object obj1, ref Object obj2) .

    同样的道理

    Object obj1 = new Object ();
    obj1 = 10;
    

    这不比 Object obj1 = 10; 顺便说一下

    要查看对象实际上是引用类型,请使用具有属性的类,例如:

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

    改变 Value 中的对象 掉期 ,您将看到对主程序的影响。

        2
  •  5
  •   Jon Skeet    15 年前

    它是一个引用类型-如果你看 documentation ,您将看到它已声明为类。所有类都是引用类型。

    是的,同样适用于 System.ValueType System.Enum -它们都是引用类型,尽管名字…但是,值类型是从它们派生的。

    编辑:您的更新显示,您真正困惑的是参数传递。看我的文章 parameter passing in C# reference/value types .

        3
  •  2
  •   Henk Holterman    15 年前

    请注意

     Object obj1 = new Object ();
     obj1 = 10;
    

    相同:

    Object obj1 = 10;
    

    因为编译器使用“boxing”进行干预以转换值类型 int 到引用类型中。在交换方法中,您将再次装箱,覆盖引用参数。

    因此,Kobi和DreamWalker的解决方案,使用参考参数,将实际工作:

     public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
    

    但这远非理想。

    更好的解决方案是一种通用方法:

     static void Swap<T>(ref T x, ref T y)
     {
        T z = x;  x = y;  y = z;
     }
    

    因此编译器可以为引用类型和值类型生成最合适的代码。

        4
  •  0
  •   TheVillageIdiot    15 年前

    作为 object 是所有对象的母亲它是引用类型

        5
  •  0
  •   fushar    15 年前

    因为obj1和obj2的运行时类型是 System.Int32 (检查) obj1.GetType().ToString() ,即值类型。交换函数中没有引用副本。相反,它只执行装箱和拆箱操作,这对实际变量没有影响。

        6
  •  0
  •   AndreyAkinshin    15 年前

    您应该这样编写代码:

    using System;
    
    class MyClass
    {
        public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
        {
            Console.WriteLine("After Swapping");
            obj1 = 100;
            obj2 = 200;
        }
    }
    
    class MainClass 
    {
        static void Main(string[] args) 
        {
            Object obj1 = new Object ();
            obj1 = 10;
    
            Object obj2 = new Object ();
            obj2 = 20;
    
            Console.WriteLine(obj1.ToString());
            Console.WriteLine(obj2.ToString());
    
            MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref'
    
            Console.WriteLine(obj1.ToString());
            Console.WriteLine(obj2.ToString());
    
            Console.ReadLine();
        }
    }
    

    您可以在中阅读有关关键字“ref”的更多信息 MSDN

    来自msdn的报价:

    传递参数(C编程 指南)

    在C中,参数可以通过 通过值或引用。经过 参数参照启用 函数成员、方法、属性, 索引器、运算符和构造函数 更改参数值的步骤 让这种变化持续下去。通过 参数引用,使用引用 或out关键字。仅为简单起见 ref关键字用于 本主题中的示例。为了更多 关于差异的信息 在参考和输出之间,见参考(c# 参考)、输出(C参考)和 使用ref和out(c)传递数组# 编程指南)。例如:

    // Passing by value
    static void Square(int x)
    {
        // code...
    }
    // Passing by reference
    static void Square(ref int x)
    {
        // code...
    }
    

    (c) MSDN - Passing Parameters (C# Programming Guide)