18

数値の型を表す型があります。この場合、私はメガワットで作業しているので、Megawatt というタイプを作成しました。Int、Double、または任意のタイプの c# 数値型と同じように、これらのメガワットを処理できるようにしたいと考えています。これは可能ですか?もしそうなら、どうすればいいですか?

例:

public class Megawatt{
    public double Value { get; set; }
}

私はこれを行うことができるようにしたい:

var startOfDay = new Megawatts{value=100};
var endOfDay = new Megawatts{value=65};
Megawatt result = startOfDay - endOfDay;

これは DateTime で可能です...ある DateTime を別の DateTime から減算して、TimeSpan を取得できます。私は似たようなことをしたいと思っています。

4

5 に答える 5

35

これまでに投稿された良い答えに加えて、あなたはあなたの型を可変値型ではなく不変構造にするべきです。これはまさに、不変の値型が設計された種類の仕事です。

struct Megawatt
{
    private double Value { get; private set; }
    public Megawatt(double value) : this()
    {
        this.Value = value;
    }
    public static Megawatt operator +(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value + y.Value);
    }
    public static Megawatt operator -(Megawatt x, Megawatt y)
    {
        return new Megawatt(x.Value - y.Value);
    }
    // unary minus
    public static Megawatt operator -(Megawatt x)
    {
        return new Megawatt(-x.Value);
    }
    public static Megawatt operator *(Megawatt x, double y)
    {
        return new Megawatt(x.Value * y);
    }
    public static Megawatt operator *(double x, Megawatt y)
    {
        return new Megawatt(x * y.Value);
    }
}

等々。2メガワットを合計することはできますが、2メガワットを掛けることはできないことに注意してください。メガワットに2倍しか掛けることができません。

ユニットを搭載したタイプをさらに追加することもできます。たとえば、タイプMegawattHourとタイプHourを作成し、MegawatttimesHourがMegawattHourを与えると言うことができます。別のタイプのジュールがあり、MegawattHourからジュールへの暗黙の変換があるとも言えます。

C#よりも冗長性の低いこれらの種類の操作をサポートするプログラミング言語は多数あります。この種のことをたくさん行う場合は、F#を調べるかもしれません。

于 2012-04-30T21:57:18.897 に答える
11

独自の演算子のオーバーロードを作成する必要があります。

サンプル :

   public static Megawatt operator +(Megawatt c1, Megawatt c2) 
   {
      return new Megawatt(c1.value+ c2.value);
   }
于 2012-04-30T21:45:54.117 に答える
2

これは、演算子のオーバーロードと呼ばれます。この記事を読むことをお勧めします:

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

プロセスに関するチュートリアルです。基本的に-、これらの型の演算子の意味を変更します。

例として(リンクから盗用)

public static Megawatt operator -(Megawatt c1, Megawatt c2) 
{
  // do whatever you want here
}

このようにして、マイナス記号はメガワットを差し引くことができます

これは、任意のタイプまたはタイプの組み合わせに対して行うことができます。必要に応じて、さらに 3 番目のタイプを返すこともできます。多くの言語がこの概念をサポートしており、非常に便利です。

于 2012-04-30T21:45:48.113 に答える
1

拡張された回答: 演算子のオーバーロードは、この場合の確実な方法です。演算子のオーバーロードは、C# の優れたオプションであり、クラス内のメソッドの代わりに演算子を便利に使用できます。

+対応する複合代入演算子などの演算子をオーバーロードすると、たとえばオーバーロードされます+=

それらの使用で想像できるように、演算子のオーバーロードは、@ RoyiNamir の回答のようstaticにキーワードを使用する必要があります。operator

答えを拡張するために、数学演算子に加えて、次のバイナリ比較演算子はペアでのみオーバーロードできます。

  1. ==!=
  2. ><
  3. >=<=

@RoyiNamirが言ったように、コード設計の推奨事項に関する限り、演算子のオーバーロードは、演算子をオーバーロードしているクラス内に存在する必要があります。

于 2012-04-30T22:09:21.847 に答える
0

独自のタイプを作成することをお勧めします。キログラムとポンドを追加する火星着陸船の問題を防ぎます。ただし、structクラスではなくsにすることをお勧めします。これにより、不変になり、null値を初期化する可能性がなくなります。また、次のようvalueなことができるようにプライベートにします。

var startOfDay = new Megawatts(100);
var endOfDay = new Megawatts(65);
Megawatt result = startOfDay - endOfDay;

IComparable<>、、IEquatable<>変換演算子などの実装も検討する必要があります。これにより、の比較を実行し、のコレクションを構築できますMegawatt

これらすべてを行うのは大変な作業です。C#CanonicalFormsを参照してください。

于 2012-04-30T22:20:26.580 に答える