我正在尝试在类Parse
中编写一个静态Matrix<T, V>
方法,该方法负责根据字符串构造正确尺寸的Matrix<T, Vector<T>>
(在此类中,支持矩阵按行向量)。存在Matrix<T, V>
的几个子类(例如Matrix2x<T>
,Matrix2x2<T>
等)。除了不同的获取/设置可访问性之外,不同的子类还具有不同的维度。该代码是从现有的功能Java代码改编而成。我和一个朋友正在尝试使用C#代替Java,这是我们更加熟悉的。
问题在于这些参数化的子类无法(隐式或强制转换)转换为用Vector<T>
基类参数化的基类。我不清楚以下代码为什么不编译,尽管我认为这是C#泛型与Java泛型相比的具体性造成的。
我想知道编译错误是否可能是由于尝试返回由类型Vector<T>
类型化的Matrix引起的,因为它是抽象的。将Vector<T>
更改为具体类(具有伪方法)并不能解决问题;编译错误仍然存在。
public static Matrix<T, Vector<T>> Parse(Func<string, Scalar<T>> parser, string str, bool mutable = false) {
MutableVector2D<T> mv2 = new MutableVector2D<T>();
Vector2D<T> v2 = mv2;
Vector<T> v = v2;
MutableMatrix2x2<T> mm22 = new MutableMatrix2x2<T>();
Matrix2x2<T, MutableVector2D<T>> m22 = mm22;
Matrix2x2<T, Vector2D<T>> m22_ = m22; // Does not compile (compilation error CS0029)
Matrix2x<T, Vector2D<T>> m2 = m22_;
Matrix<T, Vector2D<T>> m = m2;
Matrix<T, Vector<T>> answer = m; // Does not compile (compilation error CS0029)
return answer;
}
如代码片段所示,MutableVector2D<T>
可以隐式转换为Vector2D<T>
和Vector<T>
。但是,MutableMatrix2x2<T>
可能隐式转换为Matrix2x2<T, MutableVector2D<T>>
,而不是Matrix2x2<T, Vector2D<T>>
,这使我感到困惑。强制转换为Matrix2x2<T, Vector2D<T>>
(因为我了解这个问题,这没有必要)解决了任何问题。
下面列出了相关的类标题:
public sealed class MutableVector2D<T> : Vector2D<T> {...}
public abstract class Vector2D<T> : Vector<T> {...}
public abstract class Vector<T> : ICopyable<Vector<T>>, IParser<Vector<T>>, IComparable<Vector<T>>, IEnumerable<Scalar<T>> {...}
public sealed class MutableMatrix2x2<T> : Matrix2x2<T, MutableVector2D<T>> {...}
public abstract class Matrix2x2<T, V> : Matrix2x<T, V> where V : Vector2D<T> {...}
public abstract class Matrix2x<T, V> : Matrix<T, V> where V : Vector2D<T> {...}
public abstract class Matrix<T, V> : ICopyable<Matrix<T, V>>, IParser<Matrix<T, Vector<T>>>, IComparable<Matrix<T, Vector<T>>>, IEnumerable<Scalar<T>> where V : Vector<T> {...}
需要清楚的是,上面的Parse
方法与实际的解析操作无关。这只是调试调试错误的一种尝试。如果有人想知道,以下是实际的,未编译的Parse
方法:
public static Matrix<T, Vector<T>> Parse(Func<string, Scalar<T>> parser, string str, bool mutable = false) {
string[] lines = str.Split('\n');
int m = lines.Length;
if (m == 0) {
throw new ArgumentException("Cannot construct a Matrix with 0 rows.", "str");
}
string line = lines[0];
int leftIndex = line.IndexOf('[') + 1;
string[] entries = line.Substring(leftIndex, line.IndexOf(']', leftIndex)).Split(',');
int n = entries.Length;
if (n < 2) {
throw new ArgumentException("Cannot construct a Matrix with fewer than 2 columns.");
}
Scalar<T>[,] parsedEntries = new Scalar<T>[m, n];
for (int j = 0; j < n; j++) {
parsedEntries[0, j] = parser.Invoke(entries[j]);
}
for (int i = 1; i < m; i++) {
line = lines[i];
leftIndex = line.IndexOf('[') + 1;
entries = line.Substring(leftIndex, line.IndexOf(']', leftIndex)).Split(',');
if (entries.Length != n) {
throw new ArgumentException("Cannot construct a Matrix from a jagged array of entries", "str");
}
for (int j = 0; j < n; j++) {
parsedEntries[i, j] = parser.Invoke(entries[j]);
}
}
switch (n) {
case 2:
if (m == n) {
if (mutable) {
return new MutableMatrix2x2<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix2x2<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
} else {
if (mutable) {
return new MutableMatrix2x<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix2x<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
}
case 3:
if (m == n) {
if (mutable) {
return new MutableMatrix3x3<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix3x3<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
} else {
if (mutable) {
return new MutableMatrix3x<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix3x<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
}
case 4:
if (m == n) {
if (mutable) {
return new MutableMatrix4x4<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix4x4<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
} else {
if (mutable) {
return new MutableMatrix4x<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrix4x<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
}
default:
if (m == n) {
if (mutable) {
return new MutableMatrixNxN<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrixNxN<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
} else {
if (mutable) {
return new MutableMatrixNx<T>(parsedEntries); // Does not compile (compilation error CS0029)
} else {
return new ImmutableMatrixNx<T>(parsedEntries); // Does not compile (compilation error CS0029)
}
}
}
}
在此先感谢您能为我提供的任何帮助。