可变大小的值类型

时间:2011-01-05 02:28:25

标签: c# .net math

我正在尝试用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传递给函数,则对函数中元素的更改将反映在原始向量中。

我认为我的问题是我需要能够创建具有用户指定字段数的类。我不能使用数组,我也不能使用继承。

有没有人有解决方案?

编辑:此库将用于性能危急情况,因此引用类型不是选项。

3 个答案:

答案 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; }
    }
}

感谢所有回复的人。