c#=操作员问题

时间:2010-07-27 20:39:57

标签: c# operators

在C#中,我有一个简单的3D矢量类。

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a;
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

输出是,

向量a = 10,5,10

载体b = 10,5,10

在我将a.x更改为10之前我指定了一个。所以我期待

向量a = 10,5,10

向量b = 0,5,10

根据我的理解=运算符像指针一样分配对象的引用? 在C#中我不能超载=运算符。

我是否必须手动分配每个属性?

6 个答案:

答案 0 :(得分:10)

是的,因为Vecor3D是,这是完全正确的。

类是引用类型,您的b = a;语句不会复制Vector3D实例,而是复制对实例的引用。

如果你想'克隆'实例,你可以添加IClonable接口,但这或多或少被放弃了。

<X,Y,Z>类型的更好解决方案可能是使其成为结构。结构是值类型,b = a;的含义会改变(朝向你想要的)。

3D点符合结构的所有条件(小,无身份)。首选方法是将其设计为不可变的。

答案 1 :(得分:3)

是的,“ =运算符会像指针一样分配对象的引用”。因此,ab都会在内存中引用相同的单个对象。 (之前由b引用的对象不再被引用,将被垃圾回收。)

有多种方法可以解决这个问题:

  1. Vector3D设为struct而不是类。结构是类型而不是引用类型,因此b = a 将<{em}}的内容复制到变量a

  2. b课程中实施Clone方法(之前,这意味着实施Vector3D,但this is no longer recommended)。或者,您可以创建一个ICloneable构造函数,将另一个向量作为参数并创建副本。

  3. 如果您无法更改Vector3D的实施,请自行手动复制这三个值(b = new Vector3D(a.x, a.y, a.z))。

答案 2 :(得分:2)

是的,引用类型通过引用来协商。

如果您想拥有单独的实例,则需要 CLONE 您的实例。

创建一个Vector3D.Clone()方法,如下所示:

public Vector3D Clone()
{
    return new Vector3D(this.x, this.y, this.x);
}

那么你的主要应该是这样的:

static void Main(string[] args)
{
    Vector3D a, b;
    a = new Vector3D(0, 5, 10);
    b = new Vector3D(0, 0, 0);

    b = a.Clone();
    a.x = 10;

    Console.WriteLine("vector a=" + a.ToString());
    Console.WriteLine("vector b=" + b.ToString());
    Console.ReadKey();
}

但正如其他人所说,像Vector3D这样小的东西更适合作为一个不可变的结构

答案 3 :(得分:2)

您可能希望将Vector3D类更改为结构。这样可以使用值类型而不是引用类型。

您的另一个选择是实施ICloneable或使用其他方法来创建对象的深层副本。

答案 4 :(得分:1)

你可以把它变成像亨克所说的结构。你可以添加一个构造函数

struct Vector3D
{
    public int x;
    public int y;
    public int z;

    public Vector3D(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    public override string ToString()
    {
        return string.Format("{0}, {1}, {2}", x, y, z);
    }
}   

您也可以在不添加构造函数的情况下执行此操作。

b = new Vector3D() {x=0, y=0, z=0};

答案 5 :(得分:0)

无需使用struct,我建议您将Vector3D设计为不可变类。 Here是一些很好的例子。当然,对于不可变类,a.x = 10是不可能的。