1

インターフェイスを取る方法はありますか?

/// <summary>
/// Interface containing operators which operate on T
/// </summary>
public interface IScalarOperators<T>
{
    // Adds two T objects
    IOperateScalar<T> OperatorAdd { get; }
    // Subtracts two T objects
    IOperateScalar<T> OperatorSubtract { get; }
    // Multiplies two T objects
    IOperateScalar<T> OperatorMultiply { get; }
}

// Class containing all the Scalar operators for a given T
class ScalarOperators<T> : IScalarOperators<T>
{
    public IOperateScalar<T> OperatorAdd { get; private set; }
    public IOperateScalar<T> OperatorSubtract { get; private set; }
    public IOperateScalar<T> OperatorMultiply { get; private set; }
    private ScalarOperators(IOperateScalar<T> add, IOperateScalar<T> subtract, IOperateScalar<T> multiply)
    {
        this.OperatorAdd = add;
        this.OperatorSubtract = subtract;
        this.OperatorMultiply = multiply;
    }

    public static ScalarOperators<bool> CreateBool()
    {
        return new ScalarOperators<bool>(new AddBool(), new SubtractBool(), new MultiplyBool());
    }

    public static ScalarOperators<int> CreateInt()
    {
        return new ScalarOperators<int>(new AddInt(), new SubtractInt(), new MultiplyInt());
    }

    // METHOD I WANT TO ADD
    public static ScalarOperators<T> Create()
    {
      // if T == bool
      // return CreateBool()
      // if T == int
      // return CreateInt()
      // else (no definition available for T)
      // return null
    }

    // I tried something like below, but it didn't work...
    public static ScalarOperators<T> Create<T>() where T: bool
    { return CreateBool(); }

    public static ScalarOperators<T> Create<T>() where T : int
    { return CreateInt(); }

    public static ScalarOperators<T> Create<T>()
    { return null; }
}

正しい演算子セットを作成する汎用の Create メソッドが欲しいのですが、その方法がわかりません。

このメソッドからパラメーターを削除するために使用したいと思います。

    public static IMatrix<T> Add<T>(this IMatrix<T> matrix, IMatrix<T> other, IScalarOperators<T> operators)
    {
        JoinCells<T> joiner = new JoinCells<T>();
        return joiner.Join(matrix, other, null, operators.OperatorAdd);
    }

になる

    public static IMatrix<T> Add<T>(this IMatrix<T> matrix, IMatrix<T> other)
    {
        JoinCells<T> joiner = new JoinCells<T>();
        return joiner.Join(matrix, other, null, ScalarOperators<T>.Create().OperatorAdd);
    }

助けてくれてありがとう!主に、 scalarOperator オブジェクトを拡張メソッドに渡す必要はありません。定義されている T に対して ScalarOperators が変更される可能性は低いため、「デフォルト」を使用することをお勧めします。

4

3 に答える 3

3

静的クラスの代わりに IScalarOperators のファクトリを作成することをお勧めします (静的にする必要がある場合は、静的フィールドでアクセスできます)。アプリの起動時にそれらを登録し、次の例の方法で取得できます。

 public IScalarOperators<T> Create<T>()
 {
    // check if exists in dictionary
    return (ScalarOperators<T>)dict[typeof(T)];
 }

dict は Dictionary 型になります。利点は、新しい実装クラスを作成してファクトリに登録するだけで、アプリケーションの成長中に新しい IScalarOperators を追加できることです。キャストは欠点です。また、懸念事項の分離が改善され、(私の意見では) よりクリーンなコードが得られます。

于 2011-10-21T16:55:43.940 に答える
2

T の型を取得する必要があります。

Create メソッドは次のようになります。

public static ScalarOperators<T> Create()
{
    Type type = typeof(T); 
    if(type == typeof(bool))
      return CreateBool()
    if(type == typeof(int))
      return CreateInt()
    else
      return null
}
于 2011-10-21T16:09:02.283 に答える
1

ここで、対処する必要があると思われるいくつかのことが起こっています。カスタム演算子を操作対象の型から分離しようとしていますが、これは紛らわしいですが、ジェネリックの非常に幅広い概念を取り入れて特殊化しようとしています。

最初のものについては、同じ型に対して常に同じ演算子を使用します (少なくとも、int 型で bool 演算子を使用しようとすることは決してありません)。それらのために別のクラスを用意して物事を複雑にする理由はありません。後者の場合、ジェネリック クラスとジェネリック メソッドは、特定の T に対して同じように機能することを意図しています。確かに、typeof(T)静的ファクトリ メソッドで を取得し、いくつかの特定のケースでそれと比較することができます。その後、変更する必要があります。この非常に複雑なジェネリックオペランド構造のために、処理したいすべての新しい T に対してそれを行います。

オペランドのジェネリック インターフェイスを作成し、代わりにそれらの型のラッパーを実装することをお勧めします。たとえば、int は次のようにラップできます。

public interface IScalarOperators<T>
{
    IScalarOperators<T> Add (IScalarOperators<T> rightSide);
    IScalarOperators<T> Subtract (IScalarOperators<T> rightSide);
    IScalarOperators<T> Multiply (IScalarOperators<T> rightSide);
    T Unwrap();
}

public interface IMatrix<T> where T : IScalarOperators<T> { /* whatever */ }

public class CustomInt : IScalarOperators<CustomInt>
{
    private readonly int number;
    public CustomInt(int number) { this.number = number; }
    public CustomInt Unwrap() { return this; }
    public IScalarOperators<CustomInt> Add(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number + rightSide.Unwrap().number); }
    public IScalarOperators<CustomInt> Subtract(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number - rightSide.Unwrap().number); }
    public IScalarOperators<CustomInt> Multiply(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number * rightSide.Unwrap().number); }
}

その時点でIMatrix<CustomInt>、インターフェイスを介して操作し、IScalarOperators<T>必要な公開操作を実行できます。大まかな例として、 という公開されたアクセサーがあると仮定すると、2 つを足し合わせた表現を返すarrayことができます。IScalarOperators<T> result = matrix.array[0, 0].Add(matrix.array[0, 1]);その後、それに対してさらに操作を実行できます。

于 2011-10-21T17:12:52.443 に答える