2012-09-27 26 views
1
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Test1 
{ 
    public class NewGenerics<T> where T:new(int) 
    { 

    } 
} 

如何正確編寫此代碼以便與C#5.0編譯?如何在C#5.0中實現此代碼

+4

不可能,只支持new() –

+3

你想完成什麼? – rkrahl

+1

@rkrahl:顯然,OP正在尋求一種方法來放置一個通用約束,它需要'T'來構造一個具有'int'值的構造函數。 –

回答

1

一種方法是欺騙/解決方法,使其與新的(),並設置整數值的接口:

namespace Test1 
{ 
    public class NewGenerics<T> where T: IMyInterface, new() 
    { 
     private static T Create(int theInteger) 
     { 
       var inst = new T(); 
       inst.SetTheInteger(theInteger); 
       return inst; 
     } 


     .... 
    } 
} 

你可以使用Create方法來創建實例,並與整數初始化它們或任何值,你需要..

如果您可以實現所有類型的實現特定的接口是..

+0

'T'中的'int'字段不能被聲明爲'readonly'在這種情況下,雖然偶爾需要在構造函數中設置的值(只有)。 –

+0

因此,「欺騙/解決方法」..這是不可能創造這個約束,所以所有的解決方案是解決方法.. –

+0

當然,只是認爲這是很重要的缺點指出與每個解決方法,所以OP有一個更好的基礎爲他/她的決定。如果可以按照您的建議實現該接口,那麼您的解決方案當然是一個很好的解決方案,甚至可以進行編譯時檢查。 –

1

不幸的是,在當前的C#版本的泛型約束的支持集不允許指定任何[R除了無參數構造函數之外,需要構造函數簽名。

完成此操作的唯一方法是使用反射的運行時檢查。您可以使用GetType() method檢索TType實例,然後使用GetConstructors()檢索所有構造函數的ConstructorInfo實例。使用這些,你可以檢查T中的任何構造函數是否具有所需的簽名,否則拋出異常......在你的NewGenerics<T>類的每個構造函數中。

該解決方案的缺點是隻能在運行時檢查;它仍然會愉快地編譯並且只會在有人嘗試創建類的實例時拋出。