2014-09-04 430 views
1

我想實現一個類,在IntegerUpDown和DecimalUpDown WPF控件上執行泛型功能。使用下面定義的類(簡化說明)。 TDataType將爲int或float。 TUpDownControl將是要麼IntegerUpDown或DecimalUpDown WPF控件 TControlDataType將是整數或小數點C#泛型類型轉換Decimal轉換爲Float - 「不能轉換類型'T1'? 'T2'「

class MyGenericClass<TDataType, TUpDownControl, TControlDataType> 
    where TControlDataType : struct, IComparable<TControlDataType>, IFormattable 
    where TDataType  : struct, IComparable, IComparable<TDataType> 
    where TUpDownControl : CommonNumericUpDown<TControlDataType> 
{ 
    private TUpDownControl m_control; 

    public MyGenericClass(TUpDownControl ctrl) 
    { 
     m_control = ctrl; 
    } 

    public TDataType getVal() 
    { 
     TDataType val = (TDataType)m_control.Value; 
     return val; 
    } 
} 

我遇到的問題是,當我嘗試獲取價值和小數/整數轉換爲浮動/詮釋我得到錯誤 「無法轉換類型'TControlDataType?' 'TDataType'「 有沒有人有一個想法如何繞過這個?

謝謝

回答

1

該轉換不能實際工作;您不能在運行時從一種值類型轉換爲另一種值類型。
(如(float)myDecimal代碼只能是因爲編譯器生成IL實際轉換值,也不會發生仿製藥)

相反,你可以使用Convert.ChangeType()到裝箱值顯式地轉換爲任何其他數值類型。
但是,這是比較慢;它涉及兩個box/unbox對和一個虛擬接口調用。

要快,您可以使用表達式樹編譯自己的轉換器:

static class ConverterHolder<TIn, TOut> { 
    public static Func<TIn, TOut> Converter; 
    static ConverterHolder() { 
     var parameter = Expression.Parameter(typeof(TIn)); 
     Converter = Expression.Lambda<Func<TIn, TOut>>(
      Expression.Convert(parameter, typeof(TOut)), 
      parameter 
     ); 
    } 
} 
+0

感謝您的回覆。我對c#比較陌生,並且不熟悉表達式樹。你能再解釋一下嗎?例如我會有一個像ConverterHolder = Expression ....的行。表達是什麼將執行轉換? – user1400716 2014-09-04 22:24:10

+0

@ user1400716:如果您是C#的新手,表達式樹會變得複雜(這是您在運行時編譯代碼的方式)。只需要使用Convert.ChangeType。 – SLaks 2014-09-05 00:15:35

+0

非常感謝您的詳細解釋和解決方案。 – user1400716 2014-09-05 09:31:31

1

你限制不定義TDataTypeTControlDataType之間的關係,所以編譯器無法驗證,轉換會成功。不幸的是,floatdecimal之間沒有關係,您可以使用它來定義約束條件。但是,您應該可以使用TypeConverter或來提供轉換。