为什么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)的章节可能是这里最好的起点。。。然后,根据经验,处理动态
类型的方法是根据值的执行时类型(而不是编译时类型)计算编译器将执行的操作。