2013-02-01 124 views
2

來自第三方應用程序的對象值提供的值正確,但輸入的類型不正確。我試圖在我創建的一個通用方法中輸入這個對象值到我選擇的類型中。我嘲笑了一個例子來證明這個問題。.net通用打字對象與其保存的不同類型

static void Main(string[] args) 
{ 
    decimal d = 1; // this can't be changed 
    var v = Method<int>(d); // what I'm trying to do 
} 

//the code in this method can be changed 
static T Method<T>(object input) 
{ 
    T output = default(T); 

    //causes InvalidCastException 
    output = (T)input; 

    return output; 
} 

正如你所看到的值「1」是一個有效的整數,但作爲第三方應用程序類型它作爲一個小數,試圖將它轉換爲整數時翻倒。如何改變通用方法以便它不會在這種情況下崩潰?

回答

2

替換output = (T)input;有:

output = (T)Convert.ChangeType(input, typeof(T)); 
+0

這隻適用於'T'和輸入類型的有限集合(即實現'IConvertable'到IConvertable'轉換爲的項目),即使它*出現*以處理一般情況。在這方面這是誤導。 – Servy

+0

這種情況很簡單,可以滿足需要。一些錯誤處理被添加到完成這個答案,但是這是最終使用的。感謝您的輸入。 – Thundter

1

嘗試是這樣的:

static T Method<T>(object input) 
{ 
    T output = default(T); 

    var t = input.GetType(); 
    TypeConverter tc = TypeDescriptor.GetConverter(t); 
    output = (T)tc.ConvertTo(input, typeof(T)); 

    return output; 
} 

顯然你需要添加一些錯誤檢查,以確保類型兼容 - 看看方法在TypeConverter上。

你需要添加一個using System.ComponentModel;

+0

這可能是上述解決方案的矯枉過正,但我​​喜歡這個答案,而在更廣泛的情況下,這是我會選擇的。感謝您的輸入。 – Thundter

1

「鑄造」和「轉換」是兩個完全不同的事情。不幸的是,在某些情況下,C#中的語法是相同的,因此可能會混淆主題。

input只能是轉換decimal,因爲這就是它的真正原因。您可以將decimal轉換爲int,但不能轉換,而object恰好包含decimal轉換爲int

所以,如果你這樣做:

static int ToInt(object input) 
{ 
    return (int)(decimal)input; 
} 

然後它會奏效。

如果你想那裏有一個轉換運營商無論從任何inputT處理通用的情況,那麼你幾乎出於運氣。這些轉換是編譯時機制,而不是運行時機制。

+0

如果輸入是雙重的呢?讓我說,它會得到運行時錯誤 –

+0

@HosseinNarimaniRad當然。如果你的輸入是雙精度的,那麼你應該把它轉換成'double'而不是'decimal'。如果有人寫了一個有時會返回一個的方法,並且有時會返回一個,然後去找到那個人並用軟管毆打他們,因爲他們做錯了,並且沒有處理返回某個明確具有顯式對象的方法的一般情況解決方案轉換運算符爲'int'。正如我的回答所述,你可以打開類型來處理常見的類型(double,decimal,long,byte,char等),但它是不可能的。 – Servy

相關問題