为什么C#is关键字对于double返回true,而对于float返回false,即使对float的转换有效?

为什么C#is关键字对于double返回true,而对于float返回false,即使对float的转换有效?,c#,casting,floating-point,C#,Casting,Floating Point,动机:我有一个返回动态数据类型的方法。该值来自数据库,我知道该值将是浮点、双精度或字符串。如果值是字符串,我不想使用它,因此我编写了以下代码: if (value is float) { myVariable = (float)value; } 我的期望是,由于“is”关键字文档中的以下代码片段,无论实际值类型是double还是float,此代码都将执行: 如果提供的表达式为非null,is表达式的计算结果为true,并且可以将提供的对象强制转换为提供的类型,而不会引发异常 可在此处找

动机:我有一个返回动态数据类型的方法。该值来自数据库,我知道该值将是浮点、双精度或字符串。如果值是字符串,我不想使用它,因此我编写了以下代码:

if (value is float)
{
    myVariable = (float)value;
}
我的期望是,由于“is”关键字文档中的以下代码片段,无论实际值类型是double还是float,此代码都将执行:

如果提供的表达式为非null,is表达式的计算结果为true,并且可以将提供的对象强制转换为提供的类型,而不会引发异常

可在此处找到:

但是,当类型为double时,(值为float)返回false,并且不会执行赋值。但是,我将代码更改为:

if (value is double)
{
    myVariable = (float)value;
}
当值的类型是double时,它可以很好地工作——即使根据文档,我不能转换为float,因为(value是float)返回false

我的问题:为什么(值为float)在值为double(可以毫无例外地转换为float)的情况下返回false

编辑-短程序演示

class Program
{
    static void Main(string[] args)
    {
        dynamic d = 1.0;
        Console.WriteLine(d is double);
        Console.WriteLine(d is float);
        float f = (float)d;
        Console.WriteLine(f);
        Console.ReadKey();
    }
}

不确定,但我想这是因为没有隐式转换。请参见

右侧,这是因为类型为
动态
。这基本上意味着
float
cast的含义取决于值的执行时间类型

is
操作符正在检查
float
double
是否为同一类型-但它们不是,这就是返回false的原因


但是,有一个从
double
float
的显式转换,这就是强制转换工作的原因。我不会使用MSDN C#引用来计算语言行为的更详细的细节-语言规范通常是更好的选择。

您显式地将双值转换为浮点变量。非常好。 检查类型时,它与类型完全匹配。 您需要的是:

if (value is double || value is float)
{
    myVariable = (float)value;
}

请展示一个简短但完整的程序来演示问题。如果
的编译时类型实际上是
动态的
,那么这会产生显著的差异。在这个问题上,MSDN对
的描述不如C语言规范那么清晰。语言规范对我来说是一个相当吓人的文件。你能推荐哪些章节对我来说最能澄清这个问题,即我应该从铸造、动态类型或is操作符的章节开始吗?@Gaber ber:关于
is
操作符(7.10.10)的章节可能是这里最好的起点。。。然后,根据经验,处理
动态
类型的方法是根据值的执行时类型(而不是编译时类型)计算编译器将执行的操作。