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

a = b; であるため、C++ の外観で回避することはできません。C# とは別のセマンティクスが C++ にあります。C# では、a = b; a は 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

以前の投稿でこれが示唆されました:

public static implicit operator Foo(string normalString) { }

私はこのアプローチを試しました...しかし、それを機能させるには、これが必要です:

public static implicit operator 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 に答える