提问人:ummg 提问时间:11/8/2023 最后编辑:ummg 更新时间:11/8/2023 访问量:39
在 C 语言中定义无限类族“MatrixMxN”#
Defining an infinite family of classes "MatrixMxN" in C#
问:
假设我正在用 C# 编写一个线性代数库,并且我想实现矩阵乘法。当然,两个矩阵只能相乘形成,如果列数与行数一样多。因此,通常会在乘法的定义中包含参数验证步骤,在不匹配的情况下会抛出错误。这就是我最近一直在使用的 MathNet.Numerics 库中完成的方式。但是,如果矩阵维数是类型定义的一部分,那不是更好吗?A
B
AB
A
B
如果矩阵维度是类型定义的一部分,则可以在编译时而不是运行时捕获此类维度不匹配。这对于在其他上下文中约束矩阵的形状也很有用,例如在实现仅为方形矩阵定义的数学函数时。特别是,不可能因为忘记验证矩阵维度而引入错误。
然而,要实现这一点,我们需要一些语言机制,让我们定义一个无限的(至少在理论上)类族,所有的形式都是描述矩阵维度的自然数。据我所知,这在 C# 中是不可能的,但也许有办法?我们可以定义一个泛型类,但除非我们可以为每个自然数创建一个类型,否则我看不出这将如何使我们到达任何地方。我注意到一些函数式语言有一种叫做“类型级自然”的东西,这似乎对应于后一种想法。MatrixMxN
M
N
Matrix<T1,T2>
T
那么,有没有办法实现我上面描述的东西呢?如果不是 C#,那么在其他语言中呢?
答:
0赞
Logarr
11/8/2023
#1
就 C# 而言,没有这样的机制。如果有的话,Microsft 自己就不必这样做来定义Tuple<T>
public static Tuple<T1> Create<T1>(T1 item1) {
return new Tuple<T1>(item1);
}
public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) {
return new Tuple<T1, T2>(item1, item2);
}
public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) {
return new Tuple<T1, T2, T3>(item1, item2, item3);
}
public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) {
return new Tuple<T1, T2, T3, T4>(item1, item2, item3, item4);
}
public static Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) {
return new Tuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5);
}
public static Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) {
return new Tuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6);
}
public static Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) {
return new Tuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7);
}
public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) {
return new Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>(item1, item2, item3, item4, item5, item6, item7, new Tuple<T8>(item8));
}
为了获得更多乐趣,请查看整个 Tuple.cs 源文件。
评论
2赞
Ben Voigt
11/8/2023
这里的请求不是针对不同数量的泛型类型参数(如需要的,,),而是正好有两个泛型非类型参数(如C++支持非类型模板参数)Action<>
Tuple<>
Func<>
评论