2013-07-10 32 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,因爲你不能接口添加到他們自己的答案並不適用。

相關問題