Why is var defined as "double" and "not long"?

In the following code, I would expect var be resolved to Int64 , but it would be resolved to double . Why is this so?

 string a = "1234"; bool asInt = true; var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ; Console.WriteLine(b.GetType()); 
+4
source share
6 answers

There is an implicit conversion from Int64 to Double , but not the other way (due to a possible loss of accuracy in this direction).

Since both branches of the conditional type must be allowed to the same type, type b ends up being called as Double .

+12
source

You can implicitly use a long for double .

You cannot implicitly use a double for long

So, the C # compiler decided that the only option for your variable type is double .

See the table of implicit numerical conversions .

+5
source

Because the compiler must infer a type that can contain values ​​of both Int64.Parse(a) and Double.Parse(a) , without requiring an explicit cast. If long were output, precision would be lost in another porsion expression.

If you need to distinguish between types, you must declare two variables and rewrite your code:

 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()); } 
+4
source

The C # compiler infers the type from the common denominator between the two return types of your ternary code. Int64 can be implicitly converted to Double. The converse is not so.

Note that the state of the boolean code in your sample code has nothing to do with the type being inferred.

+1
source

Is this the operator’s job ?: . He must attribute all the results to one type.

PS Similar behavior of the + operator you know:

 string a = "1234"; var b = Int64.Parse(a) + Double.Parse(a) ; Console.WriteLine(b.GetType()); 

PPS To have what you want, you must use 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 Another option:

  string a = "1234"; #if asInt Int64 b = Int64.Parse(a); #else Double b = Double.Parse(a); #endif Console.WriteLine(b.GetType()); 

to determine asInt use

 #define asInt 
0
source

I am surprised that no one pointed out that if you know that the value will be a legal long value, you can change the behavior of the compiler with an explicit application and just use long .

This may or may not be useful, depending on the condition that defines the value for asInt , and depending on what you intend to do with the result of the expression. Here is an example:

 string a = "1234.56"; bool asDouble = a.Contains("."); var b = asDouble ? (long)Double.Parse(a) : Int64.Parse(a); Console.WriteLine(b.GetType()); 

In fact, in this example you do not need a conditional statement; this will work too:

 string a = "1234.56"; var b = (long)Double.Parse(a); Console.WriteLine(b.GetType()); 
In other words, it is possible that the ternary operator will not use the best solution, but the question does not provide enough context to know.
0
source

Source: https://habr.com/ru/post/1396391/


All Articles