我正在尝试用C#编写一个小型数学库。我想创建一个通用的矢量结构,用户可以在其中定义元素类型(int,long,float,double等)和尺寸。
我的第一次尝试是这样的......
public struct Vector<T>
{
public readonly int Dimensions;
public readonly T[] Elements;
// etc...
}
不幸的是,作为数组的Elements也是一种引用类型。因此,这样做,
Vector<int> a = ...;
Vector<int> b = a;
a[0] = 1;
b[0] = 2;
会导致a[0]
和b[0]
等于2。
我的第二次尝试是定义接口IVector<T>
,然后使用Reflection.Emit在运行时自动生成适当的类型。结果类看起来大致如下:
public struct Int32Vector3 : IVector<T>
{
public int Element0;
public int Element1;
public int Element2;
public int Dimensions { get { return 3; } }
// etc...
}
这看起来很好,直到我发现接口看起来像对底层对象的引用。如果我将IVector
传递给函数,则对函数中元素的更改将反映在原始向量中。
我认为我的问题是我需要能够创建具有用户指定字段数的类。我不能使用数组,我也不能使用继承。
有没有人有解决方案?
编辑:此库将用于性能危急情况,因此引用类型不是选项。
答案 0 :(得分:1)
您的班级需要Clone
个功能MemberwiseClone
如下所示:
class Vector : ICloneable {
//...
public Vector Clone() { return (Vector)this.MemberwiseClone(); }
object ICloneable.Clone() { return Clone(); }
}
答案 1 :(得分:1)
使用类似的东西:
public struct Vector<T>
{
public readonly int Dimensions;
public readonly T[] Elements;
public Vector(Vector<T> source)
{
Dimensions = source.Dimensions;
Elements = source.Elements != null ?
(T[])source.Elements.Clone()
: null;
}
public Vector<T> Clone()
{
return new Vector<T>(this);
}
// etc...
}
当您想要传递结构副本时,您必须确保使用复制构造函数或Clone
方法。
答案 2 :(得分:0)
再次,我在洗澡时顿悟了。
我想我想找的东西就像var x = new Vector<int, 4>();
,这在C#中是不可能的。所以,记住this,我目前的解决方案是:
public struct Vector<TElement, TImpl> where TImpl : struct, IImplementation<TElement>
{
private TImpl impl;
public int Dimensions { get { return impl.Dimensions; } }
public TElement this[int index]
{
get { return impl[index]; }
set { impl[index] = value; }
}
}
感谢所有回复的人。