假设我们有一个通用类的想法,名为
在C#中,从
现在,想象我们正在实现我们的
例如:下面的代码即使可以解决我的问题,但编译器仍然无法编译。
如果有人对这个问题的背景感兴趣,可以看一下https://github.com/mathnet/mathnet-numerics/issues/304。
另一个解决此问题的选项可能是使用类似于“扩展运算符”的东西(类似于扩展方法),但这些在C#中不存在。
Matrix<T>
,其中T
是数字类型(Complex
或double
或float
、int
等)。在C#中,从
float
转换为double
,从double
转换为Complex
等,都是天然的隐式转换。通常规则是,从较小的类型到较大的类型存在隐式转换。到目前为止,一切都很好。现在,想象我们正在实现我们的
Matrix<T>
类型。由于这个新类型在某种程度上也是数值型的(或者至少它持有数值),从Matrix<float>
到Matrix<double>
,从Matrix<double>
到Matrix<Complex>
等之间的隐式转换是很自然的。至少对于像乘法、加法等数学操作来说是很不错的。然而,这似乎无法正确地实现,因为隐式操作符至少要求一个类型与我们正在实现它的类相同。例如:下面的代码即使可以解决我的问题,但编译器仍然无法编译。
public abstract partial class Matrix<T>
{
/// <summary>
/// Implicitly converts a matrix to double precision complex numbers.
/// </summary>
public static implicit operator Matrix<Complex64>(Matrix<double> matrix)
{
matrix.ToComplex();
}
/// <summary>
/// Implicitly converts a matrix to double precision real numbers.
/// </summary>
public static implicit operator Matrix<double>(Matrix<float> matrix)
{
matrix.ToDouble();
}
}
它无法编译,因为“CS0556用户定义的转换必须转换为或从封闭类型转换”,假设我对此感到满意,因为它是语言规范的一部分,但是难道没有其他方法可以实现吗?
例如,这也不会编译。
public abstract partial class Matrix<double>
{
/// <summary>
/// Implicitly converts a matrix to single precision real numbers.
/// </summary>
public static implicit operator Matrix<double>(Matrix<float> matrix)
{
matrix.ToDouble();
}
}
有没有办法实现这件事,感觉很自然,所以我认为应该是可以实现的?
目前我已经创建了一个解决方法,使所有类型都能隐式转换为最大的类型,但是这并不能解决从Matrix<float>
到Matrix<double>
的转换,它只能解决到Matrix<Complex>
的转换。
public abstract partial class Matrix<T>
{
/// <summary>
/// Implicitly converts a matrix to double precision complex numbers.
/// </summary>
public static implicit operator Matrix<Complex64>(Matrix<T> matrix)
{
return matrix.Map(x =>
{
if (x is Numerics.Complex32)
{
var xc32 = (Numerics.Complex32)(object)x;
return new Complex64(xc32.Real, xc32.Imaginary);
}
return new Complex64(Convert.ToDouble(x), 0);
}, Zeros.AllowSkip);
}
}
如果有人对这个问题的背景感兴趣,可以看一下https://github.com/mathnet/mathnet-numerics/issues/304。
另一个解决此问题的选项可能是使用类似于“扩展运算符”的东西(类似于扩展方法),但这些在C#中不存在。