2013-07-10 29 views
3
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没有*,编译器会报错。如何在泛型类中使二进制乘法运算符*可用?

+1

什么是错误? –

+6

你见过[这篇文章](http://www.yoda.arachsys.com/csharp/genericoperators.html)吗? – Andrei

+0

这也是有点相关:http://stackoverflow.com/questions/390900/cant-operator-be-applied-to-generic-types-in-c和http://social.msdn.microsoft.com/Forums/en-US/6317290d-bbfb-46f6-812b-7f4252ce3f27/operator-can-be-applied-to-operands-of-type-t-and -t – Ric

回答

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定义,它将在运行时失败。

+0

我认为最后一句应该是粗体:-) –

+0

@DanielHilgarth,好点 –

3

你可以用一个方法.Multiply(T a, T b) 代替它,并与接口

public interface IMultiplyable<T> 
{ 
    T Multiply(T a, T b); 
} 
+0

我们可以在泛型类中定义一个运算符'*'吗? –

+0

没有没有约束泛型类有运营商超载 –

4

你不能这样做,使用它。乘法运算符没有为所有类型定义。但是您的泛型没有约束,因此编译器必须假设您的类的使用者可以使用任何类型,例如string

不幸的是,.NET中的泛型约束不能用于表达这种需求,即没有办法将T限制为仅定义乘法运算符的类型。

底线是:您不能在您的方案中使用泛型。您需要使用与.NET框架相同的方式,其Size(对于double)和SizeF(对于float)类型。

关于我的回答的上下文的注意事项:
如果您想为您的类提供控制权,那么Alexey的答案是正确的。
但是,如果你想用你的Square类类型,如doublefloatint,因为你不能接口添加到他们自己的答案并不适用。

相关问题