为什么对象会通过引用自动传递?

Flo*_*ein 9 c# clone pass-by-reference pass-by-value shallow-copy

在C#的pass-by-reference-pass-by-value-concept的上下文中,我有一个关于深度和浅拷贝的一般性问题:

在C#中,需要显式创建接受指针/引用的方法,以便能够将其传递给方法.但是,至少作为参数传递给方法/构造函数的对象的行为与其他对象不同.如果没有按照此处所述进行额外的克隆,它们似乎总是通过引用传递:http://zetcode.com/lang/csharp/oopii/.

为什么对象会通过引用自动传递?在这些情况下,强制克隆过程而不是处理更像int,double,boolean等对象有什么特别的好处吗?

这是代码示例,说明我的意思:

using System;

public class Entry
{

    public class MyColor
    {
        public int r = 0;
        public int g = 0;
        public int b = 0;
        public double a = 1;

        public MyColor (int r, int g, int b, double a)
        {
            this.r = r;
            this.g = g;
            this.b = b;
            this.a = a;
        }
    }

    public class A
    {
        public int id;
        public MyColor color;
        public MyColor hiddenColor;

        public A (int id, MyColor color)
        {
            this.id = id;
            this.color = color;
        }
    }

    static void Main(string[] args)
    {
        int id = 0;
        MyColor col = new MyColor(1, 2, 3, 1.0);

        A a1 = new A(id, col);
        A a2 = new A(id, col);

        a1.hiddenColor = col;
        a2.hiddenColor = col;

        a1.id = -999;
        id = 1;
        col.a = 0;

        Console.WriteLine(a1.id);
        Console.WriteLine(a2.id);

        Console.WriteLine(a1.color.a);
        Console.WriteLine(a2.color.a);

        Console.WriteLine(a1.hiddenColor.a);
        Console.WriteLine(a2.hiddenColor.a);
    }
}
Run Code Online (Sandbox Code Playgroud)

这导致:

-999
0
0
0
0
Run Code Online (Sandbox Code Playgroud)

实例MyCol总是通过引用传递,而其他参数通过值传递.我会在类中实现ICloneable MyColorA.另一方面,'#'语句存在于C#中,应该用于明确允许和传递引用.

建议欢迎!

Tho*_*que 37

为什么对象会通过引用自动传递?

他们不是.

在这些情况下,强制克隆过程而不是处理更像int,double,boolean等对象有什么特别的好处吗?

参考类型没有"克隆过程",仅适用于值类型.

我认为你混淆了不同的概念:

  • 值类型与引用类型

    对于值类型(例如原始数字类型,枚举和结构等DateTime),变量的值是对象本身.将变量分配给另一个(或通过值将其作为参数传递)会创建该对象的副本.

    引用类型(如object,string,类(未结构)等),该变量的值是对对象的引用.将变量分配给另一个(或通过值将其作为参数传递)会创建引用的副本,因此它仍然引用相同的对象实例.

  • 按值和参考传递参数

    按值传递参数意味着您传递值的副本.根据它是值类型还是引用类型,这意味着对象本身的副本或引用的副本.如果被调用者修改作为参数传递的值类型的成员,则调用者将不会看到更改,因为被调用者正在处理副本.另一方面,如果被调用者修改作为参数传递的引用类型的成员,则调用者将看到更改,因为被调用者和调用者都具有对同一对象实例的引用.

    通过引用传递参数意味着您将引用传递给变量(可以是值类型或引用类型的变量).该值不会被复制:它在调用者和被调用者之间共享.因此调用者将看到被调用者所做的任何更改(包括为参数分配新值).

    除非另有说明(使用refout关键字),否则所有参数都按值传递,包括引用类型.只是对于引用类型,传递的值是引用,但它仍然按值传递.

我建议你阅读Jon Skeet的文章参数传递C#以获得更好的解释.

  • 好解释.这个问题已被多次询问和回答,但人们仍然对这些概念感到困惑.我希望还有其他一些术语,因为"引用类型"与"通过引用传递"相混淆. (2认同)