var
次のコードでは、に解決されることを期待していますInt64
が、に解決されdouble
ます。なんでそうなの?
string a = "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());
Int64
からへの暗黙の変換がありますが、Double
その逆はありません(その方向の精度が失われる可能性があるため)。
条件付きの両方の「ブランチ」は同じタイプに解決する必要があるため、タイプは最終的に。b
として推測されDouble
ます。
暗黙的にalong
をにキャストできdouble
ます。
double
を暗黙的にキャストすることはできませんlong
したがって、C#コンパイラは、変数型の唯一の可能性はであると判断しましたdouble
。
暗黙の数値変換表を参照してください。
コンパイラは、明示的なキャストを必要とせずInt64.Parse(a)
に、両方の値を保持できる型を推測する必要があるためです。Double.Parse(a)
推測された場合long
、式の他の部分の精度が失われます。
タイプを区別する必要がある場合は、2つの変数を宣言し、コードを書き直す必要があります。
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#コンパイラは、3値の2つの戻り型の間の共通の分母から型を推測しています。Int64は暗黙的にDoubleに変換できます。逆はそうではありません。
コード例のブール値の状態は、推測された型とは関係がないことに注意してください。
これは?:
オペレーターの仕事です。すべての結果を1つのタイプにキャストする必要があります。
PS+
あなたが知っている演算子の同様の振る舞い:
string a = "1234";
var b = Int64.Parse(a) + Double.Parse(a) ;
Console.WriteLine(b.GetType());
PPSあなたが望むものを手に入れるためにあなたは使うべきですobject
:
string a = "1234";
bool asInt = true;
object b;
if(asInt) b=Int64.Parse(a); else b=Double.Parse(a);
Console.WriteLine(b.GetType());
PPPS別のオプションは次のとおりです。
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());
言い換えれば、最良の解決策は三項演算子を使用しない可能性がありますが、質問は知るのに十分なコンテキストを提供しません。