2014-09-04 422 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或来提供转换。