如何在泛型类c#中使用where for运算符?

如何在泛型类c#中使用where for运算符?,c#,generics,operator-keyword,generic-constraints,C#,Generics,Operator Keyword,Generic Constraints,嗨,我想上一节课: class Matrix <T> where T : // I don't know what to write here { T[][] elements; } 类矩阵 我不知道在这里写什么 { T[][]元素; } 我希望T能够被+和*运算符添加和倍增因为我不知道有任何内置解决方案,请查看以下内容: public abstract class BaseClass { public static BaseClass operator

嗨,我想上一节课:

class Matrix <T>
    where T : // I don't know what to write here
{
    T[][] elements;
}
类矩阵
我不知道在这里写什么
{
T[][]元素;
}

我希望T能够被+和*运算符添加和倍增

因为我不知道有任何内置解决方案,请查看以下内容:

public abstract class BaseClass
{
    public static BaseClass operator +(BaseClass p1, BaseClass p2)
    {
        return p1 + p2;
    }

    public static BaseClass operator *(BaseClass p1, BaseClass p2)
    {
        return p1 * p2;
    }
}

public class ChildClass : BaseClass
{
}

public class Matrix <T> where T : BaseClass
{
    T[][] elements;
}
公共抽象类基类
{
公共静态基类运算符+(基类p1、基类p2)
{
返回p1+p2;
}
公共静态基类运算符*(基类p1、基类p2)
{
返回p1*p2;
}
}
公共类子类:基类
{
}
公共类矩阵,其中T:BaseClass
{
T[][]元素;
}
希望这有帮助


但是不支持其他类型,如
int

可能是这样,这样对某人会有帮助。您可以通过在fabric库类中放置add、multiplicate函数来改进这一点

更新 可能正在将来自JerKimball post的操作员放入Constructor

class Matrix <T>
{
    T[][] elements;

    public Matrix(Func<T, T, T> add, Func<T,T,T> multiplicate)
    {
        this.Add = add;
        this.Mult = multiplicate;
    }

    public Matrix<T> operator +(Matrix<T> p1, Matrix<T> p2)
    {
        // correct this
        var t = Add(p1.elements[0][0], p2.elements[0][0]);
        return this;
    }

    public Matrix<T> operator *(Matrix<T> p1, Matrix<T> p2)
    {
        // correct this
        var t = Mult(p1.elements[0][0], p2.elements[0][0]);
        return this;
    }

    private Func<T, T, T> Add { get; set; }

    private Func<T, T, T> Mult { get; set; }
}

static void Main(string[] args)
{
    var m1 = new Matrix<int>((x,y) => x + y, (x,y) => x * y);
    var m2 = new Matrix<int>((x, y) => x + y, (x, y) => x * y);
}
你可以这样做:

m1.Elements[0][0] = 10;
var m3 = new Matrix<int?>((x, y) => x + y, (x, y) => x * y);
m3.Elements[0][0] = null;
m1.元素[0][0]=10;
var m3=新矩阵((x,y)=>x+y,(x,y)=>x*y);
m3.元素[0][0]=null;

我强烈建议您查看Skeet和Gravell先生的“MiscUtil”库:

其中包含一个令人难以置信的“泛型数学运算符”实现,它应该与您创建泛型矩阵数学类的尝试非常吻合。它实际上让我想起了python,以及它如何处理直接引用操作符函数的问题

(除了@jon skeet:这有可能成为Nuget的一部分吗?)

测试中的一些示例用法:

double sumOperator = 0;
for (int i = 0; i < COUNT; i++)
{
    sumOperator = Operator.Add(sumOperator, rand.NextDouble());
}

int sumOperator = 0;
for (int i = 0; i < COUNT; i++)
{
    sumOperator = Operator.Add(sumOperator, rand.Next(MAXVALUE));
}
double-sum运算符=0;
for(int i=0;i
这是不可能的,因为未受约束的泛型类型被假定为类型
Object
,该类型不定义算术运算符。因此,似乎需要指定一个接口

但是,原语类型(Int32、Double等)将算术运算有效地定义为静态方法(实际上编译器专门处理它们并内联生成代码),而C#中的接口无法定义静态方法(尽管CLR的设计实际上允许)。因此,不能用C#编写满足支持算术运算要求的接口;即使可以编写,原始类型也不会继承它,因此它仍然无法工作

最终的结果是,在C#中没有办法做你想做的事情

如果您确实尝试了它,您会得到一个类似于的错误

Operator '+' cannot be applied to operands of type 'T' and 'T'

如果您对该消息进行web搜索,您会发现关于可能的解决方法的各种讨论。

不幸的是,对于实现特定运算符的类型没有约束。有一些我个人不会使用的变通方法,比如强制转换到
动态
。一个可能的解决方案虽然是一个有趣的问题,但它是否可以通过隐式指定类型(例如用于
int
的iMatrix和用于
float
的fMatrix)来工作?如果有另一个类支持
+
*
但不继承
基类
,这将不起作用。例如,
int
@Default确实如此,感谢您指出这一点。我已经更新了答案以添加此限制。这样我就不能给元素赋值(如0或任何数字,也不能将它们转换为int或任何不可为null的类型),您能提供一个您不能执行的示例吗?
Operator '+' cannot be applied to operands of type 'T' and 'T'