如何在泛型类c中使用where for运算符
本文关键字:where for 运算符 泛型类 | 更新日期: 2023-09-27 17:58:08
嗨,我想要一个类:
class Matrix <T>
where T : // I don't know what to write here
{
T[][] elements;
}
我希望T可以通过+和*运算符
我强烈建议您查看Messrs Skeet and Gravell的"MiscUtil"库:
http://www.yoda.arachsys.com/csharp/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));
}
这是不可能的,因为无约束泛型类型被假定为Object
类型,它没有定义算术运算符。因此,您似乎需要指定一个接口。
但是,基元类型(Int32、Double等)将算术运算有效地定义为静态方法(实际上编译器会专门处理它们并内联生成代码),而C#中的接口不能定义静态方法(尽管CLR的设计实际上允许这样做)。因此,不能用C#编写满足支持算术运算要求的接口;即使可以编写,基元类型也不会继承它,所以它仍然无法工作。
最终的结果是没有办法在C#中做你想做的事情。
如果你真的尝试了,你会得到一个类似的错误
Operator '+' cannot be applied to operands of type 'T' and '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;
}
希望这能有所帮助。
但是不支持其他类型,如int
。
也许这样会对某人有所帮助。您可以通过在结构库类中放入add、multiplicate函数来改进这一点。
更新可能会将JerKimball岗位的操作员投入
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);
}
更新2
只需提供这样的属性访问权限:
public T[][] Elements { get; set; }
你可以这样做:
m1.Elements[0][0] = 10;
var m3 = new Matrix<int?>((x, y) => x + y, (x, y) => x * y);
m3.Elements[0][0] = null;