这可能吗?指定任何泛型类型,只要在其上定义了 + 操作

Is this possible? Specify any generic type as long as the + operation is defined on it

我不确定这是否可行,但如果可行那将很有用。

我正在尝试在名为 Matrix<T> 的 class 中编程。目的是能够拥有各种数据类型的矩阵,例如整数、浮点数、双精度数等。

我现在要定义加法:

    public static Matrix<T> operator +(Matrix<T> first, Matrix<T> second)
    {
        if (first.dimension != second.dimension)
        {
            throw new Exception("The matrices' dimensions do not match");
        }
        Matrix<T> add = new Matrix<T>(first.dimension);

        for (int i = 1; i <= first.rows; i++)
        {
            for (int j = 1; j <= first.columns; i++)
            {
                add[i,j] = first[i,j] + second[i,j];
            }
        }
        return add;
    }

add[i,j] = first[i,j] + second[i,j]; 存在问题,因为操作 + 未在 T.

类型的一般对象上定义

我只想指定矩阵,其中 T 是定义了加法的类型。所以,我可以制作一个 ints、floats、doubles 等的矩阵,但是如果我尝试定义一个矩阵,比如说 int[] s,我希望它抛出异常,因为 + 没有为 int[]s 定义。

所以,除了写 T,有没有什么方法可以告诉计算机“只要定义了运算符 +,它就可以接受任何泛型类型在类型上?或者,这是不可能的,我必须单独定义一个 int 的矩阵,float 的矩阵,等等?

编辑:我看不出 与此有什么关系 - 我看不到那里的运算符。如果它们是相关的,有人可以解释一下吗?

目前这是不可能的(至少不会失去编译时安全性或更改 API)但是启用预览功能和 System.Runtime.Experimental nuget 你可以使用 IAdditionOperators 来限制 T 来定义 + 运算符。我会说将此接口也添加到 Matrix 本身可能是个好主意:

class Matrix<T> : IAdditionOperators<Matrix<T>, Matrix<T>, Matrix<T>> where T : IAdditionOperators<T, T, T>
{
   public static Matrix<T> operator +(Matrix<T> left, Matrix<T> right)
    {
        // swap to real implementation here
        T x = default;
        T y = default;
        Console.WriteLine(x + y);
        return default;
    }
}

另请参阅:

可以使用反射

class Int
{
    readonly int v;

    public int Get => v;

    public Int(int v)
    {
        this.v = v;
    }

    public static Int operator +(Int me, Int other) => new Int(me.v + other.v);
}


class Arr<T>
{
    T[] _arr;

    public Arr(T[] arr)
    {
        _arr = arr;
    }

    public T this[int index] => _arr[index];

    public static Arr<T> operator+(Arr<T> me, Arr<T> other)
    {
        var addMethod = typeof(T).GetMethod("op_Addition");
        if (addMethod == null)
            throw new InvalidOperationException($"Type {typeof(T)} doesn't implement '+' operator");
        var result = me._arr.Zip(other._arr)
            .Select(elements => addMethod.Invoke(null, new object[] { elements.First, elements.Second }))
            .Cast<T>()
            .ToArray();
        return new Arr<T>(result);
    }
}

[Test]
public void TestAdd()
{
    var firstArray = new Arr<Int>(new[] { new Int(1), new Int(2) });
    var secondArray = new Arr<Int>(new[] { new Int(2), new Int(3) });
    var sum = firstArray + secondArray;
    Assert.AreEqual(3, sum[0].Get);
    Assert.AreEqual(5, sum[1].Get);
}

将示例简化为数组。 不幸的是,即使 T 没有实现 add 运算符,它也会编译,所以你会在运行时得到一个异常。您还可以检查添加方法是否具有正确的签名(returns T 并采用两个 T)。如果您在理解代码方面需要帮助,请告诉我!