C# 中的英尺到米转换器坏了?

Feet to Meter Converter in C# is broken?

我正在尝试制作一个简单的英尺到米转换器,但发生了这种情况:

using System;
using System.Windows;
using System.Windows.Controls;

namespace CoolConversion
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        decimal feet;
        decimal meter;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            feet = Convert.ToDecimal(Feet.Text);
            meter = feet / 3.281;
        }
    }
}

这是我目前的代码。起初,feet & meter 是整数,但我无法将整数除以 3.281。我将它们更改为小数,现在出现此错误:

Error CS0019 Operator '/' cannot be applied to operands of type 'decimal' and 'double'

如果我不能用整数除以小数,如果我不能在小数上使用 / 符号,我该如何除以小数?

默认情况下,3.281 本身就是一个双精度浮点数。您可以通过在数字末尾添加 m 来使用 decimal-文字表示法。

meter = feet / 3.281m;

为简洁起见,如果您曾经使用过声明为 double 的变量,您可以随时将其转换为小数,以防您需要使用两种不同的类型执行计算每个操作数。

double feetToMeterValue = 3.281;
meter = feet / (decimal)feetToMeterValue;

这也适用于其他类型,但请注意,在转换为特定类型时会失去精度,即 double > float 和更明显的 decimalint.

这里的问题是编译器认为您的常量 3.281double 类型。如果您打算使用 decimal 之类的类型,则必须附加 m 后缀。同样,对于 float 类型,您必须附加 f 后缀。根据 MSDN:

By default, a real numeric literal on the right side of the assignment operator is treated as double.


float

Therefore, to initialize a float variable, use the suffix f or F, as in the following example:
float x = 3.5F;


double

However, if you want an integer number to be treated as double, use the suffix d or D, for example:
double x = 3D;


decimal

If you want a numeric real literal to be treated as decimal, use the suffix m or M, for example:
decimal myMoney = 300.5m;


我的建议

你真的应该在使用之前确定你实际需要使用的类型。在将 feet 转换为 meters 的情况下,我会使用 doublefloatdouble 通常是这种情况,因为它更精确。

private double feet = 0.0d;
private double meters = 0.0d;

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    feet = Convert.ToDouble(Feet.Text);
    meters = feet / 3.281d;
}

decimal 类型通常用于保存货币值,其中 doublefloat 用于此类计算。此外,这不是必需的,但如果您曾经使用过多个相似类型,例如 floatdoubledecimal;使用每个后缀来清楚地传达您打算使用的类型总是一个好主意。


最后的笔记

您可以像其他人指出的那样转换为 decimal,但是当您可以使用 3.281m 指定 decimal 时,这是不必要的转换。在性能很重要的环境中,您应该尽可能避免不必要的转换。

另一方面,在尝试转换之前,您确实应该确保您尝试转换的文本是有效值。我更喜欢使用 TryParse(如果我没记错的话,所有数字类型都应该有一个 TryParse 方法)。这背后的原因是,如果我按照您的方法当前的工作方式在您的文本框中键入 123a,它会立即爆炸。解决这个问题非常简单:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    if (double.TryParse(Feet.Text, out feet))
        meters = feet / 3.281d;
    else
        MessageBox.Show($"You've entered an invalid value: {Feet.Text}.");
}