gpt4 book ai didi

c# - 泛型类的隐式转换仅限于某些类型

转载 作者:太空狗 更新时间:2023-10-29 23:49:40 26 4
gpt4 key购买 nike

假设我们有泛型类的想法 Matrix<T>其中 T是数字类型( Complexdoublefloat , int 等)。

我们在 C# 中从 float 进行隐式转换是很自然的至 double , 来自 doubleComplex .一般规则是我们有从较小类型到较大类型的隐式转换。到目前为止一切顺利。

现在假设我们正在实现我们的 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# 中不存在这些东西。

最佳答案

我知道创建通用向量或矩阵类并让它进行代数运算(加法、减法、乘法)的唯一方法是发出 MSIL调用运算符的代码(例如 operator + )。然后它可以与具有 static MyType operator + (MyType a, MyTYpe b)任何类型一起使用定义以及内置类型。

参见 this answer of mine有关更多详细信息的类似问题。

使用 Operation<T> 中的静态方法你可以有下面的示例代码

public class Matrix<T>
{
T[,] elements;

static readonly Func<T,T> add = Operation<T>.Add;

public static Matrix<T> operator + (Matrix<T> A, Matrix<T> B)
{
Matrix<T> result = new Matrix<T>(rows,cols);
for(int i=0; i<rows; i++)
{
for(int j=0; j<cols; j++)
{
result[i,j] = add(A[i,j], B[i,j]);
}
}
return result;
}
// rest of algebra
}

所以如果你有一个 Complex64定义的类具有 operator +定义你可以声明Matrix<Complex64>并像var C = A+2*B那样做代数直接地。运行时将为内置类型或自定义类型调用适当的运算符。对速度的影响很小,因为查找适当的调用方法的反射在首次使用时对每种类型只执行一次一次

关于c# - 泛型类的隐式转换仅限于某些类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41795162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com