2013-07-07 46 views
2

這是我遇到的一個奇怪的問題。我有一個返回object的函數。在特定情況下,我確定該對象是int,但調用此函數的另一個函數需要float。我能得到這個工作的唯一方法是如下:需要雙重轉換才能將int從對象轉換爲浮點型

private object parser(string expr) {...} 

private float parseFloat(string expr) 
{ 
    ... 
    object result = parser(expr); 
    if (result is int) 
     return (float)(int)result; 
    else 
     return (float)result; 
} 

沒有這種類型的檢查,我無法得到它在所有的工作,即使我知道解析器函數的結果在這種情況下,是一個int。 (你可以看到它在調試器。)我寧願走行簡單:

private float parseFloat(string expr) 
{ 
    ... 
    return (float)parser(expr); 
} 

(類型檢查預先完成,parseFloat不應該用不會計算爲float的表達式被稱爲或int。)是否有必要對此變量進行重複投票的某些原因?我顯然不希望在所有情況下雙投它,因爲如果從parser回報率爲一個float,它將它截斷爲int第一,我們不希望出現這種情況。 (是的,我試着用SingleInt32更換floatint等沒有任何區別。)

我看到this question,但是它依賴於預先知道的類型,並且它提供了唯一的解決辦法是這種雙重鑄造技巧,這在我的情況下,將截斷float小號除非我首先做一個類型檢查,這還需要一個額外的局部變量來保存結果。有什麼辦法可以避免這個額外的步驟嗎?

+1

你爲什麼不提供一個'ParseFloat',如果你肯定知道這是一個? –

+0

這就是......的目的。傳遞給'ParseFloat'表達可以是一個浮動文本(這是在處理...代碼)或返回浮點數的函數。解析器的工作是解釋這樣的函數(實際上可能是幾個嵌套函數)。 –

+2

這是一個常見問題。我在2009年回答了,在這裏:http://ericlippert.com/2009/03/03/representation-and-identity/ –

回答

6

當您取消裝入object框中的值類型時,必須使用正確的轉換。從一種數字類型到另一種數字類型的轉換是在拆箱之後進行的額外轉換。

在你的情況,但是,第二投真的是隱含的,所以您可以簡化一點點:首先

if (result is int) 
    return (int)result; 
else 
    return (float)result; 

爲什麼你已經裝箱的值類型?如果你不知道什麼類型是盒裝的,爲了取消裝箱,你通常必須以你的方式檢查is

但請注意,與(IConvertible)類型,如這些內置的數字類型,你也可以使用Convert類,所以:

return Convert.ToSingle(result); 

它看起來更漂亮,但我不認爲它更快。它可能會做同樣的類型檢查。

如果parser只給出了數字類型,如果由於某種原因你堅持拳擊這兩種類型,你還不如他們框到IConvertible,使涉及到改變的返回類型是這樣的:

private IConvertible parser(string expr) {...} 

那麼你的代碼可以去這樣:

IConvertible result = parser(expr); // it's some number boxed in an IConvertible reference type 
return result.ToSingle(null); // instance method in IConvertible 
+0

改進 - 儘管如此,仍然需要臨時變量和類型檢查。那真的沒有辦法嗎?只有其他的東西我可以想到的是將其減少到'::'而不是'if' \'else',但仍然不能保存額外的步驟。 –

+0

好的,編輯中的'Convert.Tosingle'技巧確實可以解決問題,但目前難以在兩者之間進行性能比較。似乎正常投射應該足夠聰明以根據需要取消裝箱並重新輸入結果?無論如何,至少對於內置類型。 –

+0

關於你最後的編輯 - 不,「解析器」可以返回一些非數字類型,這就是爲什麼它返回「object」。它還處理'bool','string's,一個自定義的Vector4類和'List's的所有上述。一些腳本函數甚至有一個'void'返回值(雖然在引擎蓋下它只返回'null')。每種類型都有自己的Parse功能,就像上面的ParseFloat一樣。這裏張貼的代碼太多了,我只是簡化它來顯示問題。 –