在C#,.Net 4 ...
的背景下给定一个数据源对象,该对象通过索引从双精度数组中提供顶点,其中顶点包含10个双精度数,其成员为Px,Py,Pz,Nx,Ny,Nz,S,T,U,V和后备数组包含基于数据源的步幅,偏移和计数属性的所有或顶点成员的任何子集。数据源可以简化为:
public class DataSource
{
private double[] data;
private int offset, stride, count;
public double[] ElementAt(int index)
{
double[] result = new double[count];
var relativeIndex = index * stride + offset;
Array.Copy(data, relativeIndex, result, 0, count);
return result;
}
.
.
.
}
一些消费者会对double []的返回类型感兴趣,但大多数会将数据作为PointNf类型请求,其中N是所采用的顶点成员数(Point1f ... Point10f)。 Point类型的消费者不关心源的步幅,而源为大于其步幅的成员提供零。例如来自步幅3的来源的Point4f将填充数据[i + 0],数据[i + 1],数据[i + 2],0。
显然,DataSource可以公开方法GetPoint1f(int index),GetPoint2f(int index)等。这些类型的解决方案可能最好给出固定的返回类型集,元素大小等。但是......
如果语法如...
,有哪些可能的解决方案Point3f point = SomeDataSource.ElementAt[index];
...或者类似的是被要求/要求/想要的?...利弊?...什么不该做的例子?......严厉的语言?
答案 0 :(得分:5)
如果语法如...
,有哪些可能的解决方案请求/要求/期望Point3f point = SomeDataSource.ElementAt[index];
...或类似的?
这是用户定义的隐式转化的主要候选者:
// I’m guessing it’s a struct, but can be a class too
public struct Point3f
{
// ...
public static implicit operator Point3f(double[] array)
{
// Just for demonstration: in real code,
// please check length and nullity of array first!
return new Point3f(array[0], array[1], array[2]);
}
// You can declare one that goes the other way too!
public static implicit operator double[](Point3f point)
{
return new double[] { point.Px, point.Py, point.Pz };
}
}
答案 1 :(得分:1)
您如何知道index
处的PointNf类型?
无论如何,工厂模式就是你所追求的,但问题是如何根据你的对象实现它。基本工厂看起来像这样
public T GetElementAt<T>(int index) where T : new() {
Type type = typeof(T);
T result = new T()
if (type==typeof(Point3f)) {
result.X = data[index];
result.Y = data[index+1];
result.Z = data[index+2];
}
else if (type==typeof(Point2f) {
result.X = data[index];
result.Y = data[index+1];
}
return result;
}
注意:这不会编译,因为X,Y,Z没有为T定义,但你不想再使用它。
缺点是必须检查每种点类型的T类型。如果您使用自己可以修改的PointNf类,有几种解决方案可以改进它。一个例子是使每个PointNf类使用类似IPointDataProvider
的方法从公共接口(void PopulateData(double[] data, int index)
)派生,为此它们实现自己的细节,并且您的工厂方法可以简化为
public T GetElementAt<T>(int index) where T : IPointDataProvider, new() {
T result = new T()
result.PopulateData(data, index)
return result;
}
一个点的示例实现就像。
一样简单class Point2f : IPointDataProvider {
double X, Y;
void IPointDataProvider.PopulateData(double[] data, int index) {
X = data[0];
Y = data[1];
}
}