2016-09-20 100 views
2

我不明白为什么这种方式不起作用,我可以直接从double转换为decimal而没有问题,但是出人意料的是,如果它在内部通用类,这个片段更好的解释它:泛型十进制不能从双精度转换为

public class TestCollection<T> 
{ 
    public void Add(object value) 
    { 
     //When T is decimal, then I get 
     // System.InvalidCastException 
     var t = (T) value; 
    } 
} 

public void Main() 
{ 
    var t = new TestCollection<decimal>(); 
    double doub = 10; 

    var decim = (decimal) doub; //Works!  
    t.Add(doub);    //throws! 
} 

System.InvalidCastException是未处理由用户代码 的HResult = -2147467262 消息=指定的转换无效。 Source = Wpf StackTrace: at Wpf.TestCollection`1.Add(Object value)in C:\ Users \ btord \ Source \ Repos \ Live-Charts \ Examples \ Wpf \ JimmyTheTestsGuy.xaml.cs:line 15 at Wpf.JimmyTheTestsGuy..ctor()在C:\用户\ btord \源\回购\活图表\实例\ WPF \ JimmyTheTestsGuy.xaml.cs:管线35 在Wpf.MainWindow..ctor()在C:\用户\ btord \来源\回购\活图表\例子\ WPF \ MainWindow.xaml.cs:行56 的InnerException:

+0

这是因为你传递对象,而不是增加一倍。 – steryd

+2

为什么'value'对象的类型而不是'T'? – Lee

+0

@Lee我有2个重载,一个T和一个对象,我得到当对象过载被称为错误,这是代码 –

回答

5

它失败,因为完全相同的原因如下失败:

short s = 1; 
object o = s; 
var i = (int)o; //Runtime error 

原因是一个盒装值只能被拆箱到其真实的类型。在你的情况下,你正在装箱double,并试图将其解开到decimal。这是不允许的。

我会回推整个设计。您有一个T s的通用集合。您的Add方法应该简单地接受T,并让调用者承担转换为正确类型的负担。如果这不是一个有效的解决方案,那么一起去除泛型并简单地实现一组对象。

+0

我知道了,谢谢的一小部分,任何想法找到一个解决办法? –

+0

@ bto.rdz'public void Add(dynamic value)'似乎可以工作,如果你用'dynamic'确定的话。 – Quantic

+0

@ bto.rdz请参阅我的答案更新。 – InBetween

4

你可以使用Convert.ChangeType为:

public void Add(object value) 
{ 
    var t = Convert.ChangeType(value, typeof(T)); 
} 

见琴:https://dotnetfiddle.net/0Tfgyz

+0

谢谢,我很担心这种方法的性能比较,因为这种方法是在我的代码 –

+0

好真的很重要。也许你应该首先介绍它,看看它是否是一个不行。刚刚找到了一个处理'ChangeType'性能的stackoverflow答案:http://stackoverflow.com/questions/1532197/faster-version-of-convert-changetype – Nico

1

如果您需要物品T的欧洲工商管理学院,你可以用你的Add方法的动态。

public void Add(object value) 
{ 
     //When T is decimal, then I get 
     // System.InvalidCastException 
     dynamic t1 = value; 
     var t = (T)t1; 
}