[英]How to implement a generic hierarchy of structures with injected functionality
[英]Is it possible to implement generic-dimensional data structures?
我正在编写一些自己的数据结构,例如二进制树和四叉树以及kD树。 是否可以以允许任意数量的尺寸来编写它们?
就像是:
KDTree<2, string> twoDTree = new KDTree<2, string>();
twoDTree[3,4] = "X,Y = (3,4)";
KDTree<4, string> fourDTree = new KDTree<4, string>();
fourDTree[0,1,2,3] = "x1,x2,x3,x4 = (0,1,2,3)";
我现在唯一的解决方案是显式创建每个维,因为它们是自己的类:
TwoDTree<string> twoDTree = new TwoDTree<string>();
twoDTree[3,4] = "X,Y = (3,4)";
FourDTree<string> fourDTree = new FourDTree<string>();
fourDTree[0,1,2,3] = "x1,x2,x3,x4 = (0,1,2,3)";
但这会复制粘贴大量的代码,应该可以以某种方式重用它们。
并非如此,但我看到了更多选择:
将尺寸传递到构造函数中,并使用像这样的索引器:
public string this[params int[] indexes] {
get {
// return the data fr the index
}
}
这具有在编译时不“类型安全”的缺点(例如,将不检查传入的尺寸)。
或创建一堆接口并使用Reflection.Emit创建实例,这些实例在运行时实现正确的接口:
public interface IMultiDimensional<T> {
int Dimensions {
get;
}
int Rank(int dimension);
}
public interface I1Dimensional<T>: IMultiDimensional<T> {
T this[int index] {
get;
set;
}
}
public interface I2Dimensional<T>: IMultiDimensional<T> {
T this[int index1, int index2] {
get;
set;
}
}
public interface I3Dimensional<T>: IMultiDimensional<T> {
T this[int index1, int index2, int index3] {
get;
set;
}
}
public interface I4Dimensional<T>: IMultiDimensional<T> {
T this[int index1, int index2, int index3, int index4] {
get;
set;
}
}
public static TDimensional CreateMulti<TDimensional, TType>() where T: IMultiDimensional<TType> {
// emit a class with Reflection.Emit here that implements the interface
}
I4Dimensional<string> four = CreateMulti<I4Dimensional<string>, string>();
four[1,2,3,4] = "abc";
您可以将多维数组用作通用参数,如下所示:
KDTree<string[,,,]>
但是,如果不将其公开给调用者,就无法编写索引到多维数组的通用代码:
public class KDTree<MDT> {
// ...
public MDT Data { get; }
}
var twoTree = new KDTree<string[,]>();
twoTree.Data[3,4] = "X,Y = (3,4)";
您还可以考虑使用锯齿状数组而不是多维数组。 然后,您可以创建定义数据类型的通用类,并在构造函数中指定要使用的维数:
public class KDTree<T> {
private readonly T[][] m_Data;
public KDTree( int rows, int columns ) {
m_Data = new T[rows][];
for( int r = 0; r < rows; r++ )
m_Data[r] = new T[columns];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.