我有一个sql datareader...从中必须获取一个十进制值。
(decimal)datareader["percent"] 与 Convert.ToDecimal(datareader["percent"])之间有什么区别?
这两种方法的优点和缺点是什么?
只有当datareader["percent"]
返回的对象是Decimal
类型时,转换才会成功。如果对象是任何可转换为Decimal
类型的类型,包括int
、long
、short
等,那么转换也将成功。更一般地说,任何实现IConvertible
接口并从IConvertible.ToDecimal()
返回有效值的内容都可以传递给Convert.ToDecimal()
。
例如:
csharp> object a = (int)1;
csharp> a.GetType();
System.Int32
csharp> var dec = (decimal)a;
System.InvalidCastException: Cannot cast from source type to destination type.
at Class3.Host (System.Object& $retval) [0x00000] in <filename unknown>:0
at Mono.CSharp.Evaluator.Evaluate (System.String input, System.Object& result, System.Boolean& result_set) [0x00000] in <filename unknown>:0
at Mono.CSharpShell.Evaluate (System.String input) [0x00000] in <filename unknown>:0
csharp> var dec = Convert.ToDecimal(a);
csharp> dec;
1
csharp> dec.GetType();
System.Decimal
我不清楚具体的十进制转换,但是我知道对于整数,Convert方法会四舍五入,而强制类型转换会截取小数部分,例如(int)7.6得到的结果是7,Convert.ToInt32(7.6)得到的结果是8。虽然这和你的例子无关,但是需要记住这一点。
第一个 ((decimal)datareader["percent"]
) 是一个显式转换 (强制类型转换)。它的作用是将编译器拆箱或将目标值 (datareader["percent"]
) 强制转换为 decimal
。这将导致 InvalidCastException
,除非 datareader["percent"]
是 decimal
或装箱的 decimal
。
第二个运行的是 .NET 的代码,检查 datareader["percent"]
是什么对象类型,并尝试以适当的方式将其转换为 decimal
。如果值是任何数字类型(例如 int
),则会成功。
(decimal)value
为什么能够工作? - Nigel Touch(decimal)value
是一种有效的转换方式。(decimal)(object)value
是错误的拆箱方式(首先将 double
装箱为 object
),会抛出异常。(double)(object)value
是正确的拆箱方式,可以正常工作。 - Jon0
。
例如,以下所有内容都将返回0
。Convert.ToByte(null);
Convert.ToDecimal(null);
Convert.ToDouble(null);
Convert.ToInt64(null);
Convert.ToInt32(null);
但是,如果应用了强制转换,将会抛出InvalidOperationException
,并提示“可空对象必须具有值”。
编辑
强制类型转换表示对象是指定类型或其派生类。转换则表示虽然它可能不是该类型或派生类,但存在将其转换为目标类型的方法。
例如:
string a = "1234";
object b = a;
// success, a is really a string
string c = (string)b;
// fails because b is not actually an int
int d = (int)b;
// success because there is way to convert the numeric string to an int
int e = Convert.ToInt32(b);
编辑:@cdhowie 指出了一个好点,这应该更加描述性
Convert.ToDecimal(new object());
--> System.InvalidCastException: 无法从源类型转换为目标类型。 - cdhowie
(long)(object)(int)1
总会产生运行时错误,即使(long)(int)1
可以成功。 - cdhowie(decimal)value
为什么能够工作? - Nigel Touch(decimal)(object)1.0
。您将收到一个InvalidCastException。请参见此ideone。) - cdhowie