2012-02-29 50 views
0

我有一個類以下面的方式定義。接口和具體類型都有一個類型參數,我期望它是一個double,int,decimal或DateTime。我已經添加了一個IComparable的where約束,但是這個類做了一些重的數字提升,所以我想避免裝箱和拆箱。類定義如下:哪裏限制通用類型與Double Typeparam - 裝箱/拆箱?

public interface INumericClass<T1, T2> where T1:IComparable 
    where T2:IComparable 
{ 
    void DoLongNumericOperation(); 
} 

public class NumericClass<T1, T2> : INumericClass<T1, T2> where T1:IComparable 
    where T2:IComparable 
{  
    private IList _innerArray1 = new T1[1000000]; 
    private IList _innerArray2 = new T2[1000000];  
    public void DoLongNumericOperation()  
    {   
     for(int i = 0; i < _innerArray1.Count; i++)   
     {    
      // some computation goes on in here    
      // for example, it could be    
      double aConstant = 123.45; 
      double aScalar = 56.7; 
      _innerArray1[i] = (Convert.ToDouble(_innerArray1[i]) * aConstant + aScalar); 
      _innerArray2[i] = (Convert.ToDouble(_innerArray2[i]) * aConstant + aScalar);   
     }  
    } 
} 

這些類將被宣佈,以調用代碼類似如下

var numeric = new NumericClass<int, double>(); 
numeric.DoLongNumericComputation(); 

現在國內我處理多種類型的方式來使用的投噸至一倍。不過我擔心的是,既然我已經指定T是一個IComparable類型的參數,那麼拆箱/裝箱正在進行。另外DateTime提供額外的開銷。在這種情況下,我正在做的是將.Ticks屬性轉換爲雙精度值並對其進行操作。

我歡迎任何有關CLR背後發生的事情的信息,以及改進性能的建議(如API更改),以強制鍵入每個數字操作以提高性能和內存使用率。

編輯:我還要補充上述實現次優的,如果你申報NumericClass它開始投擲距離的Tx投翻番。儘管我不確定,但我只能假設它通過IComparable進行投射。

+0

'INumericClass'只有一個類型參數。但是,當您將它用於'NumericClass'時,您提供了兩個類型參數。哪個是對的? – cadrell0 2012-02-29 14:24:19

+0

道歉,我會更新 – 2012-02-29 14:24:54

+2

代碼片段質量很低。先編譯它。請解釋如何讓它接下來演員。 – 2012-02-29 14:31:35

回答

1

請參閱Generic operators

+0

有趣的是,謝謝 - 雖然簡單的答案:0 – 2012-02-29 14:42:42

2

沒有看到一個更完整的例子,這裏是我可以推薦的。

public interface IConvertToDouble<T> 
    where T : IComparable 
{ 
    double Convert(T input); 
    T ConvertBack(double input); 
} 

public class NumericClass<T, U> 
    where T : IComparable, 
      U : IComparable 
{ 
    private IConvertToDouble<T> _tConverter; 
    private IConvertToDouble<U> _uConverter; 
    private List<T> _internalTs; 
    private List<U> _internalUs; 

    public NumericClass(IConvertToDouble<T> tConverter, IConvertToDouble<U> uConverter) 
    { 
     _tConverter = tConverter; 
     _uConverter = uConverter; 
     _internalTs = new List<T>(); 
     _internalUs = new List<U>(); 
    } 

    public void DoLongNumericOperation() 
    { 
     for(int i = 0; i < innerArray.Length; i++) 
     { 
      // some computation goes on in here 
      // for example, it could be 
      double aConstant = 123.45; 
      double aScalar = 56.7 
      _internalTs[i] = _tConverter.ConvertBack(_tConverter.Convert(_internalTs[anIndex]) * aConstant + aScalar); 
      _internalUs[i] = _uConverter.ConvertBack(_uConverter.Convert(_internalUs[anIndex]) * aConstant + aScalar); 
     } 
    } 
} 

現在你不需要投你的通用對象或具有特定類型邏輯NumericClass。

+0

Hello cadrell0,有趣的是,這正是我所做的。不涉及鑄造,我有一個類型不可知的「轉換器」類。然而,我所關心的是這種方法中的拳擊/拆箱。你有什麼光可以解決這個問題嗎? – 2012-02-29 14:42:26

+0

我的IConvertToDouble接口不是類型不可知的。它需要每種類型的實現。這是爲了避免拳擊/拆箱。 – cadrell0 2012-02-29 14:49:03

+1

無論如何,是不是擔心拳擊/拆箱微觀優化? – jrummell 2012-02-29 14:51:39