問題

「Addable」と呼ばれる基本的なarithmaticを可能にするクラスを定義したいとします。追加可能なものを追加することができます。

 abstract class Addable
{
   public abstract Addable Add(Addable X, Addable Y)
}
 

Addableを実装する正しい方法は何ですか?以下は動作しません。

numberは継承された抽象メンバAddable.Add(Addable、Addable)を実装していません。

 class Number : Addable
{
     public int Value;

     public Number(int Val)
     {
        Value = Val;
     }

     public Number Add(Number X, Number Y)
     {
         return new Number(X.Value + Y.Value);
     }
}
 

問題は、Add takes(Number、Number)がジェネリックではない引数として使用されることだと思いますが、進める方法はわかりません。

編集:いくつかの人々がこれが何のために使用されるべきかを知るように要求したので、私に詳しく教えてください。 私はいくつかのオブジェクトの最大値を取ることに依存するアルゴリズムを使用しています。ユースケースによっては、これらのオブジェクトは数値またはディストリビューションです。上記の例を残すために、私はこれらの数値やディストリビューションを追加する必要があると思います。だから私は次のようなコードを持っていたい:

 Addable LongAlgorithm(Addable X, Other parameters)
{
   ... // Lots of code that may contain X
   Z = Add(X,Y)
   ... // Code Using Z.

   return Answer // Answer is of the same type as X in the input.
}
 

編集2:この質問が与えられたフィードバックでは、 " Interface vs Baseクラス"の領域に漂っているようです。おそらく、この質問を読んだ他の人がその質問を照らしているかもしれません。

私は質問がはっきりしていることを願っています。私はS.Oを初めて使っています。できるだけガイドラインに固執しようとしましたが、質問をより明確にするために変更してうれしいです。

  ベストアンサー

そのAddableベースクラスが必要な理由と、どのように使用されるかによってすべてが異なります。これを説明するためにあなたの質問を更新する価値があります。あなたのユースケースを満たさない可能性があります:

 public interface IAddable<T>
{
    T Add(T x, T y);
}

public class Number : IAddable<Number>
{
    public int Value { get; set; }

    public Number(int value)
    {
        Value = value;
    }

    public Number Add(Number other)
    {
        return new Number(Value + other.Value);
    }
}
 

もちろん、抽象基本クラスもここで使用できます。

 public abstract class Addable<T>
{
    public abstract T Add(T x, T y);
}
 

class Foo : IAddable<Bar> ではなく class Foo : IAddable<Foo> しかできないことを確認したい場合は、ジェネリック型の制限を追加できます。

 public interface IAddable<T> where T : IAddable<T>
{
    T Add(T x, T y);
}
 

あなたの編集に応じて:

上記のタイプを使用してこれを行う:

 T LongAlgorithm<T>(T x, Other parameters) where T : IAddable<T>
{
   ... // Lots of code that may contain x
   T z = x.Add(y);
   ... // Code Using z

   return z;
}
 

Add メソッドを変更して、インスタンスメソッドであり、別のインスタンスに追加することに注意してください。

シグネチャをAdd(x, y)として保持したい場合は、おそらく次のようなものが必要です。

 public class Number
{
    public int Value { get; set; }
    public Number(int value)
    {
        Value = value;
    }
}

public interface IAdder<T>
{
    T Add(T x, T y);
}

public class NumberAdder : IAdder<Number>
{
    public static readonly NumberAdder Instance = new NumberAdder();
    private NumberAdder() { }
    public Number Add(Number x, Number y)
    {
        return new Number(x.Value + y.Value);
    }
}

T LongAlgorithm<T>(T x, IAdder<T> adder, Other parameters)
{
   ... // Lots of code that may contain x
   T z = adder.Add(x, y);
   ... // Code Using z

   return z;
}
 

次にそれを

 Number z = LongAlgorithm(new Number(3), NumberAdder.Instance, ...);
 

  同じタグがついた質問を見る

c#abstract-class