这可能吗?指定任何泛型类型,只要在其上定义了 + 操作
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
是定义了加法的类型。所以,我可以制作一个 int
s、float
s、double
s 等的矩阵,但是如果我尝试定义一个矩阵,比如说 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;
}
}
另请参阅:
- Generic math (especially section 关于试用,注意 - 推荐 VS 2022)
可以使用反射
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)。如果您在理解代码方面需要帮助,请告诉我!
我不确定这是否可行,但如果可行那将很有用。
我正在尝试在名为 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
是定义了加法的类型。所以,我可以制作一个 int
s、float
s、double
s 等的矩阵,但是如果我尝试定义一个矩阵,比如说 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;
}
}
另请参阅:
- Generic math (especially section 关于试用,注意 - 推荐 VS 2022)
可以使用反射
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)。如果您在理解代码方面需要帮助,请告诉我!