2016-09-20 103 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; 
}