2011-02-08 57 views
15

我正在使用特定任務的.NET plattform,它是預編譯的而不是OpenSource。 對於一些我需要擴展這個類的任務,而不是從它繼承。我只是想添加一個方法。如何爲帶有類型參數約束的泛型類型編寫擴展方法?

起初我想告訴你一個dummycode現有類:

public class Matrix<T> where T : new() { 
    ... 
    public T values[,]; 
    ... 
} 

我想通過以下方式擴展這個類:

public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) { 
     T result = 0; 
     ... 
     return result; 
    } 
} 

我已經得到了許多谷歌這句法因此不知道鏈接是否正確。編譯器告訴我沒有錯誤,但最終它不起作用。最後,我想以下面的方式調用這個功能:

Matrix<int> m = new Matrix<int>(); 
... 
int aNumber = m.getCalcResult(); 

所以,任何人有一個想法?感謝您的幫助!

問候焾

+0

你覺得爲什麼它不工作?它是否會拋出異常? – 2011-02-08 01:52:58

+1

這是使用擴展方法的正確方法,但是由於T最初並不限於「int」,所以應該使用`T result = default(T)`而不是'T result = 0'。除此之外,您應該檢查以確保您的使用聲明包含您的MatrixExtension類。您可以通過直接調用`MatrixExtension.getCalcResult(m)`來檢查它是否正常工作。 – 2011-02-08 01:55:05

+0

至少IDE迫使我調用這樣的方法: m.getCalcResult (); 但是當我嘗試編譯此,我得到一個其它的錯誤: >「矩陣」不包含「的GetValue」的定義,並沒有擴展方法「的GetValue」接受一個類型的第一個參數「矩陣」可能是發現(您是否缺少使用指令或程序集引用?) 順便說一下,調用該方法的這種方式沒有意義,因爲通用參數T已被分配。 – 2011-02-08 01:59:21

回答

23

您需要在擴展方法上添加相同的類型參數約束。

這是我嘗試在編譯並運行了你的例子最親密的重建,沒有任何錯誤:

public class Matrix<T> where T : new() { 
    public T[,] values; 
} 


public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) where T : new() { 
     T result = new T(); 
     return result; 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     Matrix<int> m = new Matrix<int>(); 
     int aNumber = m.getCalcResult(); 
     Console.WriteLine(aNumber); //outputs "0" 
} 
-2

有你看着「裝飾」 ......

Sample showing Decorator patterns

裝飾器允許你創建自己的屬性和方法的類,而不從一個做直接推導具體的類。然後,您可以將它「應用」到任何其他物體。然後,您可以應用使用您正在嘗試使用的額外方法或屬性。

此示例是一個簡單的快速查找出這樣的例子通過構建「選項」自身附加到「汽車」 ......

2

眼下,唯一的「錯誤」我看是這樣的:

T result = 0; 

你可以修改成:

T result = default(T); 

在值類型的情況下,這將是零,因此這將是安全的。

但是,當您到達列出的「...」部分時,您會發現這很難。基本類型(int,double等)沒有實現可用於計算數學的方法。這是一個long time, very highly voted request on Connect,順便說一句。

雖然有解決方法,但它們使生活變得非常困難。與C++中的模板不同,C#的泛型實際上不支持任意類型的類型安全數學運算。