C# 编译时的向量数学维度一致性检查

C# 编译时的向量数学维度一致性检查,c#,C#,我正在用C#创建一个线性代数库,我想在编译时强制执行维度不一致性错误。我已经实现了一个类似的解决方案,其中我使用的特性是一个唯一映射到整数的类。问题是,对于我希望向量具有的每个可能大小,我都需要创建一个具有唯一名称的类来表示它 下面是该实现的一个示例: public class Vector<T> where T: ISize, new() { static readonly T size = new T(); List<double> values;

我正在用C#创建一个线性代数库,我想在编译时强制执行维度不一致性错误。我已经实现了一个类似的解决方案,其中我使用的特性是一个唯一映射到整数的类。问题是,对于我希望向量具有的每个可能大小,我都需要创建一个具有唯一名称的类来表示它

下面是该实现的一个示例:

public class Vector<T> where T: ISize, new()
{
    static readonly T size = new T();
    List<double> values;

    public Vector(List<double> values)
    {
        if (values.Count != size.Size)
            throw new IndexOutOfRangeException();

        this.values = new List<double>(values);
    }

    public double Get(int index)
    {
        return values[index];
    }

    public Vector<T> Add(Vector<T> other)
    {
        var vv = new List<double>();

        for (int ii = 0; ii < size.Size; ++ii)
            vv.Add(other.Get(ii) + this.values[ii]);

        return new Vector<T>(vv);
    }
}

public interface ISize
{
    int Size { get; }
}

public class S1 : ISize
{
    public int Size
    {
        get { return 1; }
    }
}

public class S2 : ISize
{
    public int Size
    {
        get { return 2; }
    }
}
公共类向量,其中T:ISize,new()
{
静态只读T大小=新T();
列表值;
公共向量(列表值)
{
if(values.Count!=size.size)
抛出新的IndexOutOfRangeException();
this.values=新列表(值);
}
公共双Get(int索引)
{
返回值[索引];
}
公共向量添加(向量其他)
{
var vv=新列表();
用于(int ii=0;ii
下面是它的用法示例:

class Program
{
    static void Main(string[] args)
    {
        var v1 = new Vector<S2>(new List<double>() { 1, 2 });
        var v2 = new Vector<S2>(new List<double>() { 10, -4 });
        var z1 = new Vector<S1>(new List<double>() { 10 });

        // works
        var v3 = v1.Add(v2);

        // complie-time error
        var z2 = z1.Add(v1);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var v1=新向量(新列表(){1,2});
var v2=新向量(新列表(){10,-4});
var z1=新向量(新列表(){10});
//工作
var v3=v1.Add(v2);
//康普莱时间误差
var z2=z1.相加(v1);
}
}

这对于我来说非常有效,除了我需要为每个可能的向量大小创建一个不同的ISize实现之外。我有没有办法实现Vector类来解决这个问题?

为了获得编译时错误,需要使用不同的类型。C#没有一个概念,让我们定义一个类型参数,它本身接受一种值参数——这就是你需要做的

因此,我认为你的要求是不可能的

我认为可能有一种方法可以使用匿名类型为向量实例族创建唯一的类型,但这很奇怪,我认为它不会提供您想要的类型安全性


C++在模板中有这样一个概念(所以这并不是不合理的),只是在C#中不可能实现。

您可以创建一个带有编译时类型检查的N维
向量
类,但它相当混乱。我们在这里创建的是LISP风格的链表,但它是通过泛型类型参数创建的,而不是通过字段创建纯粹的对象引用

public interface IVector
{
    double Value { get; }
    IVector Tail { get; }
}
public class Vector<T> : IVector
    where T : IVector
{
    internal Vector(double value, T tail)
    {
        Value = value;
        Tail = tail;
    }

    public double Value { get; private set; }
    public T Tail { get; private set; }

    public Vector<Vector<T>> Add(double value)
    {
        return new Vector<Vector<T>>(value, this);
    }
}
internal class EmptyVector : IVector
{
    public double Value
    {
        get { throw new NotImplementedException(); }
    }

    public IVector Tail
    {
        get { return null; }
    }
}

public static class Vector
{
    public static readonly Vector<IVector> Empty = new Vector<IVector>(
        0, new EmptyVector());
    public static IEnumerable<double> AllValues(this IVector vector)
    {
        IVector current = vector;
        while (current != Vector.Empty && current != null)
        {
            yield return current.Value;
            current = current.Tail;
        };
    }
}
这允许您编写一个接受特定大小向量的方法。它不方便,也不可扩展,但可以工作。如果希望(例如)三维矢量作为参数,可以编写:

public static void Foo(Vector<Vector<Vector<IVector>>> vector)
{
    var first = vector.Value;
    var second = vector.Tail.Value;
    var third = vector.Tail.Tail.Value;
}
公共静态void Foo(向量)
{
var first=向量值;
var second=vector.Tail.Value;
第三个变量=vector.Tail.Tail.Value;
}

没有“非类型模板参数”的C++等价物,我认为这是不可能的。
public static void Foo(Vector<Vector<Vector<IVector>>> vector)
{
    var first = vector.Value;
    var second = vector.Tail.Value;
    var third = vector.Tail.Tail.Value;
}