是否有在C#中重载赋值运算符的解决方法?

时间:2008-11-15 15:34:09

标签: c# operator-overloading

与C ++不同,在C#中,您不能重载赋值运算符。

我正在为具有非常大数字的算术运算做一个自定义Number类,我希望它具有内置数值类型的外观,如int,decimal等。我已经重载算术运营商,但任务仍然是......

以下是一个例子:

Number a = new Number(55); 
Number b = a; //I want to copy the value, not the reference

该问题是否有解决方法?

7 个答案:

答案 0 :(得分:42)

您可以使用'implicit'关键字为赋值创建重载:

假设您有类似Foo的类型,您认为可以从字符串中隐式转换。 您可以在Foo类中编写以下静态方法:

public static implicit operator Foo(string normalString)
{
    //write your code here to go from string to Foo and return the new Foo.
}

完成后,您可以在代码中使用以下内容:

Foo x = "whatever";

答案 1 :(得分:28)

我真的不清楚你真的需要这个。之一:

  • 您的数字类型应该是结构(很可能 - 数字是结构的最常见示例)。请注意,您希望类型的所有类型(int,decimal等)都是结构体。

或:

  • 您的数字类型应该是不可变的,使每个变异操作都返回一个新实例,在这种情况下,您无需在分配时复制数据。 (事实上​​,你的类型应该是不可变的,无论它是否是一个结构。可变结构是邪恶的,一个数字肯定不应该是一个可变的引用类型。)

答案 2 :(得分:6)

由于a = b,你将无法解决C ++外观问题。在C ++中有其他语义而不是在C#中。在C#中,a = b;指向像b这样的同一个对象。在C ++中,a = b改变了a的内容。两者都有起伏。就像你做的那样

MyType * a = new MyType();
MyType * b = new MyType(); 
a = b; /* only exchange pointers. will not change any content */

在C ++中(它将丢失对第一个对象的引用,并创建内存泄漏。但是让我们忽略它)。你不能在C ++中为assign操作符重载。

解决方法很简单:

MyType a = new MyType();
MyType b = new MyType();

// instead of a = b
a.Assign(b);

免责声明:我不是C#开发人员

你可以像这样创建一个只写属性。然后做一个.Self = b;上方。

public MyType Self {
    set {
        /* copy content of value to this */
        this.Assign(value);
    }
}

现在,好。因为它违反了最不惊讶的原则(POLS)。如果一个人做a.Self = b;

,人们不会期望改变

答案 3 :(得分:3)

不是在传递引用时复制数据,而是可以使类不可变。当类是不可变的,有多个引用它不是一个问题,因为它不能被更改。

更改数据的操作当然会返回新实例。

答案 4 :(得分:2)

之前的帖子暗示了这一点:

  

public static implicit operator Foo(string normalString){}

我试过这种方法......但为了使它成功,你需要这个:

public static implicit operator Foo(Foo original){}

并且编译器不允许您从您的确切类型中获取隐式转换函数,也不允许您拥有自己的任何基类型。这是有道理的,因为它将成为覆盖赋值运算符的后门方式,C#不希望这样做。

答案 5 :(得分:0)

这是一个适合自己的解决方案:

public class MyTestClass
{
   private int a;
   private string str;

   public MyTestClass()
   {
      a = 0;
      str = null;
   }

   public MyTestClass(int a, string str)
   {
      this.a = a;
      this.str = str;
   }

   public MyTestClass Clone
   {
      get
      {
         return new MyTestClass(this.a, this.str);
      }
   }
}

代码中的其他地方:

MyTestClass test1 = new MyTestClass(5, "Cat");
MyTestClass test2 = test1.Clone;

答案 6 :(得分:-3)

也许您正在寻找的东西可以使用C#访问器来解决。

http://msdn.microsoft.com/en-us/library/aa287786(v=vs.71).aspx