35

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

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

这是一个例子:

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

有解决该问题的方法吗?

4

7 回答 7

44

您可以使用 '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";
于 2009-02-05T15:49:44.497 回答
29

我仍然不清楚你是否真的需要这个。任何一个:

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

或者:

  • 您的 Number 类型应该是不可变的,使每个突变操作都返回一个新实例,在这种情况下,无论如何您都不需要在分配时复制数据。(事实上​​,你的类型应该是不可变的,无论它是否是结构体。可变结构体是邪恶的,数字当然不应该是可变引用类型。)
于 2008-11-15T16:46:50.570 回答
6

您将无法以 C++ 的外观解决它,因为 a = b; 在 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++ 中的赋值运算符。

解决方法很简单:

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

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

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

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

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

现在,这不好。因为它违反了最小意外原则(POLS)。如果一个人做了 a.Self = b; 就不会期望 a 改变。

于 2008-11-15T15:44:01.027 回答
3

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

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

于 2008-11-15T16:29:24.710 回答
2

较早的一篇文章建议了这一点:

公共静态隐式运算符 Foo(string normalString) { }

我尝试了这种方法......但要让它工作,你需要这个:

公共静态隐式运算符 Foo(Foo original) { }

并且编译器不会让您从您的确切类型或您自己的任何基本类型中获得隐式转换函数。这是有道理的,因为这将是一种覆盖赋值运算符的后门方式,而 C# 不想允许这种方式。

于 2011-01-06T20:26:57.520 回答
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;
于 2016-10-10T15:48:02.470 回答
-4

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

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

于 2012-09-07T16:53:09.180 回答