2013-02-07 24 views
6

您好我想有一類:如何使用泛型類c#的操作符?

class Matrix <T> 
    where T : // I don't know what to write here 
{ 
    T[][] elements; 
} 

我想噸至是可添加和+ multiplyable和*運營商

+2

不幸的是,對於實現特定操作符的類型沒有限制。有些我不會親自使用的解決方法,比如投射到「動態」。 – JosephHirn

+0

[只限於整數](http://stackoverflow.com/questions/32664/c-sharp-generic-constraint-for-only-integers)與可能的解決方案是[IConvertible](http://stackoverflow.com/a/756995/95573) – SwDevMan81

+0

雖然是一個有趣的問題,它是否會通過隱式指定類型(例如用於'int'的iMatrix和用於'float'的fMatrix)來工作? – Default

回答

1

。我不知道有任何內置的解決方案,檢查出:

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,將不被支持。

+1

如果有另一個類支持'+'和'*'但不繼承'BaseClass',這將不起作用。例如'int' – Default

+0

@Default事實上,謝謝你指出這一點。我已更新答案以添加此限制。 –

1

可能是這樣對別人有幫助。您可以通過在fabric-library類中添加,乘法函數來改善這一點。

UPDATE 可能將運營商從JerKimball後進入counstructor

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; 
+0

這種方式我不能給元素的價值(如0或任何數字,也不能將它們轉換爲int或任何非空類型) –

+0

你能提供一個你不能做的例子嗎? – gabba

2

我會強烈建議你看一看從先生飛碟雙向和Gravell了「MiscUtil」庫:

http://www.yoda.arachsys.com/csharp/miscutil/

內包含的是一個令人難以置信的「通用數學運算」的實施,應很好地與您嘗試創建通用矩陣數學類。它實際上提醒了我(一點)python以及它如何處理直接引用操作符函數。

(一邊@喬恩 - 雙向飛碟:這使得它的方式的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)); 
} 
1

這是不可能的,因爲不受約束的泛型類型被假定爲類型Object,它沒有定義算術運算符。因此,你似乎需要指定一個接口。但是,原始類型(Int32,Double等)將靜態方法(實際上是編譯器專門處理它們並在內部生成代碼)中有效地定義算術運算,並且C#中的接口無法定義靜態方法(儘管設計的CLR實際上允許它)。因此,在C#中沒有寫滿足支持算術運算要求的接口;即使它可以被寫入,原始類型也不會繼承它,所以它仍然不起作用。

最終的結果是,沒有辦法在C#中做你想做的事。

如果你嘗試,你會得到類似的錯誤

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

如果你對這個消息做一個網絡搜索,你會發現有關可能的解決方法的各種討論。