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 对象传递给扩展方法,我更喜欢使用“默认值”,因为 ScalarOperators 不太可能针对定义的任何 T 进行更改。

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>接口对 an 进行操作,并执行您想要的任何公开操作。作为一个粗略的示例,假设您有一个名为 的公开访问器array,您可以说IScalarOperators<T> result = matrix.array[0, 0].Add(matrix.array[0, 1]);并获得将两者相加的表示。然后,您可以对其执行任何进一步的操作,依此类推。

于 2011-10-21T17:12:52.443 回答