为什么 var 被解析为 Double 而不是 Long?

发布于 2025-01-05 00:22:29 字数 243 浏览 0 评论 0原文

在下面的代码中,我希望 var 解析为 Int64,但它解析为 double。为什么会这样呢?

string a =  "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());

In the following code, I would expect var to get resolved to an Int64, but it gets resolved to a double. Why is it so?

string a =  "1234";
bool asInt = true;
var b = (asInt) ? Int64.Parse(a) : Double.Parse(a) ;
Console.WriteLine(b.GetType());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

北风几吹夏 2025-01-12 00:22:29

有从 Int64Double 的隐式转换,但反之则不然(由于该方向可能会损失精度)。

由于条件的两个“分支”需要解析为相同的类型,因此 b 的类型最终被推断为 Double

There is an implicit conversion from Int64 to Double but not the other way (due to possible loss of precision in that direction).

Since both "branches" of the conditional need to resolve to the same type, the type of b ends up being inferred as a Double.

踏雪无痕 2025-01-12 00:22:29

您可以将 long 隐式转换为 double

您无法将 double 隐式转换为 long

因此,C# 编译器决定变量类型的唯一可能是 double

请参阅隐式数字转换表

You can implicitly cast a long to a double.

You cannot implicitly cast a double to a long

So the C# compiler decided the only possibility for your variable type was double.

See Implicit Numeric Conversions Table.

灯角 2025-01-12 00:22:29

因为编译器需要推断出一个可以同时保存 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());
}

Because the compiler needs to infer a type that can hold values of both Int64.Parse(a) and Double.Parse(a) without requiring an explicit cast. If long was inferred, precision would be lost in the other porsion of the expression.

If you need to distinguish the type, you have to 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());
}
撩动你心 2025-01-12 00:22:29

C# 编译器根据三元数的两个返回类型之间的公分母来推断类型。 Int64 可以隐式转换为 Double。反之则不然。

请注意,代码示例中布尔值的状态与推断的类型无关。

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

Note that the state of the Boolean in your code example has nothing to do with the inferred type.

江湖正好 2025-01-12 00:22:29

这是 ?: 运算符的工作。它应该将所有结果转换为一种类型。

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

This is the work of ?: operator. It should cast all results to one type.

P.S. The similar behavior of + operator you know:

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

P.P.S. To have what you want you should 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());

P.P.P.S. Another option is:

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

to define asInt use

#define asInt
我只土不豪 2025-01-12 00:22:29

我很惊讶没有人指出如果您知道该值将是合法的 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());

换句话说,最好的解决方案可能不会使用三元运算符,但问题没有提供足够的上下文来了解。

I'm surprised nobody has pointed out that if you know the value will be a legal long value, you can change the compiler's behavior with an explicit cast, and just use long.

This may or may not be helpful, depending on the condition that determines the value for asInt, and depending on what you intend to do with the result of the expression. Here's 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 don't need the conditional operator; this would work too:

string a =  "1234.56"; 
var b = (long)Double.Parse(a);
Console.WriteLine(b.GetType());

In other words, it's possible that the best solution wouldn't use the ternary operator, but the question doesn't give enough context to know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文