abstract class Shape<T>
{
public abstract T Area();
}
class Square<T> : Shape<T>
{
T side;
public Square(T side)
{
this.side = side;
}
public override T Area()
{
return this.side * this.side;
}
}
错误1运算符'*'不能应用于'T'类型和'T'类型的操作数。
编译器抛出错误,因为*
没有this.side*this.side
。如何在泛型类中使用二进制乘法运算符*
?
答案 0 :(得分:4)
你做不到。没有为所有类型定义乘法运算符。但是你的泛型没有约束,因此编译器必须假设你的类的使用者可以使用任何类型,例如string
。
不幸的是,.NET中的泛型约束不能用于表达这种要求,即没有办法将T
仅限制为定义乘法运算符的类型。
底线是:您不能在场景中使用泛型。您需要使用与Size
(适用于double
)和SizeF
(适用于float
)类型的.NET框架相同的方式。
请注意我的答案背景:
如果你想为你可以控制的任意课程提供你的课程,Alexey有正确的答案
但是,如果您希望将Square
类与double
,float
或int
类型一起使用,则他的答案不适用,因为您无法为其添加界面
答案 1 :(得分:4)
您不能使用*
运算符本身,但您可以通过生成使用此运算符的表达式来解决它:
static class Operators
{
public static T Multiply<T>(T x, T y)
{
return OperatorCache<T>.Multiply(x, y);
}
static class OperatorCache<T>
{
static OperatorCache()
{
Multiply = MakeBinaryOperator(ExpressionType.Multiply);
}
static Func<T, T, T> MakeBinaryOperator(ExpressionType type)
{
var x = Expression.Parameter(typeof(T), "x");
var y = Expression.Parameter(typeof(T), "y");
var body = Expression.MakeBinary(type, x, y);
var expr = Expression.Lambda<Func<T, T, T>>(body, x, y);
return expr.Compile();
}
public readonly static Func<T, T, T> Multiply;
}
}
然后您可以像这样使用它:
public override T Area()
{
return Operators.Multiply(this.side, this.side);
}
当然,您可以将其他运算符添加到Operators
类;请记住如果您使用的运算符没有为T
定义,它将在运行时失败。
答案 2 :(得分:3)
您可以使用方法.Multiply(T a, T b)
替换它
并将其与界面
public interface IMultiplyable<T>
{
T Multiply(T a, T b);
}