在以下代碼中,我期望var
可以解析爲Int64
,但它會解析爲double
。爲什麼這樣?爲什麼var會以Double而不是Long來解析?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
在以下代碼中,我期望var
可以解析爲Int64
,但它會解析爲double
。爲什麼這樣?爲什麼var會以Double而不是Long來解析?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
有一個隱式轉換從Int64
到Double
而不是其他方式(由於在該方向上的精度可能損失)。
由於條件的兩個「分支」都需要解析爲相同類型,因此b
的類型最終被推斷爲Double
。
有道理。有什麼辦法可以在需要時創建Int64類型的變量'b',並在需要時創建Double(基於bool'asInt')?當然,在if語句中初始化它是行不通的,因爲它的作用域限制在 – xbonez 2012-02-14 12:35:02
@xbonez - 不在條件運算符中。該類型必須在運行時推斷/確定。你可以使用'dynamic'。 – Oded 2012-02-14 12:36:38
嗯...謝謝。我會研究動態的。我知道數學運算在雙打上比較慢,所以我希望在不需要時不要使用雙精度。我會研究動態的,但如果這不起作用,我想我會忍受它。 – xbonez 2012-02-14 12:37:52
您可以隱式將long
投射到double
。
不能隱式轉換一個double
到long
所以C#編譯器決定了變量類型的唯一可能性是double
。
因爲編譯器需要推斷可以保存Int64.Parse(a)
和Double.Parse(a)
的值而不需要顯式強制轉換的類型。如果推斷出long
,則表達式的另一個偏差將會失去精度。
如果您需要區分類型,您必須聲明變量和重寫代碼:
if (asInt)
{
var b = Int64.Parse(a); // will infer a `long`
Console.WriteLine(b.GetType());
}
else
{
var b = Double.Parse(a); // will infer a `double`
Console.WriteLine(b.GetType());
}
C#編譯器從公分母推斷兩個返回類型之間的類型你三元。 Int64可以隱式轉換爲Double。反過來並非如此。
請注意,代碼示例中布爾的狀態與推斷類型無關。
這是?:
操作員的工作。它應該將所有結果都轉換爲一種類型。
P.S. +
運營商的類似行爲,你知道:
string a = "1234";
var b = Int64.Parse(a) + Double.Parse(a) ;
Console.WriteLine(b.GetType());
P.P.S.有你想要你應該使用什麼object
:
string a = "1234";
bool asInt = true;
object b;
if(asInt) b=Int64.Parse(a); else b=Double.Parse(a);
Console.WriteLine(b.GetType());
P.P.P.S.另一種選擇是:
string a = "1234";
#if asInt
Int64 b = Int64.Parse(a);
#else
Double b = Double.Parse(a);
#endif
Console.WriteLine(b.GetType());
定義asInt中使用
#define asInt
我很驚訝,沒有人指出,如果你知道值將是一個法律long
值,可以更改編譯器的行爲與明確的強制轉換,並只使用long
。
根據確定asInt
的值的條件以及您打算對錶達結果做什麼,這可能會也可能不會有所幫助。這裏有一個例子:
string a = "1234.56";
bool asDouble = a.Contains(".");
var b = asDouble ? (long)Double.Parse(a) : Int64.Parse(a);
Console.WriteLine(b.GetType());
事實上,在這個例子中,你不需要條件運算符;這將工作太:
string a = "1234.56";
var b = (long)Double.Parse(a);
Console.WriteLine(b.GetType());
換句話說,它可能是最好的解決辦法不會用三元運算符,但問題並沒有給予足夠的情況下就知道了。
即使編譯,我有點驚訝。我認爲三元的兩邊都必須返回相同的類型,儘管我認爲有一個從長到雙的隱含對話 – 2012-02-14 12:32:36
有。 ,)這解釋了這一點。 – TomTom 2012-02-14 12:34:07