[英]generic casting from object-boxed type
為什么這樣做:
decimal dec = new Decimal(33);
double dd = (double) dec;
Console.WriteLine(dd);
但不是這個:
decimal dec = new Decimal(33);
object o = (object)dec;
double dd = (double) o;
Console.WriteLine(dd);
第二個例子拋出:
System.InvalidCastException:指定的強制轉換無效。
這個問題來自我有一個通用方法的情況
public T GetValue(string q)
從數據源獲取值。 這些值的類型是未知的,但該方法假定它可以將值轉換為T.有時,值將是對象{decimal},T將是double,在這種情況下將拋出InvalidCastException。 但原則上這不應該是一個問題,因為值是一個小數(盡管是一個對象的盒子),可以轉換為double。
我該如何處理這個問題呢?
您只能將盒裝值類型轉換回裝入的確切類型 。如果從盒裝類型到您要投射的類型的隱式或顯式轉換無關緊要 - 您仍然必須轉換為盒裝類型(為了取消裝箱),然后從那里拿走它。
在示例中,這意味着兩個連續的強制轉換:
double dd = (double) (decimal) o;
或者,使用Convert
方法:
double dd = Convert.ToDouble(o);
當然,這不適用於您的實際用例,因為您無法立即從泛型類型參數轉到ToDouble
。 但只要目標類型是IConvertible
,您就可以這樣做:
double dd = (double)Convert.ChangeType(o, typeof(double));
其中泛型類型參數T
可以替換為double
。
后者不起作用,因為十進制值被裝入一個對象。 這意味着要獲得值,您必須先使用相同的轉換語法取消裝箱,因此您必須按照以下兩個步驟執行此操作:
double dd = (double) (decimal) o;
請注意,第一個(decimal)
是拆箱, (double)
是轉換。
這可以使用Convert.ChangeType
完成:
class Program
{
static void Main(string[] args)
{
decimal dec = new Decimal(33);
object o = (object)dec;
double dd = GetValue<double>(o);
Console.WriteLine(dd);
}
static T GetValue<T>(object val)
{
return (T)Convert.ChangeType(val, typeof(T));
}
}
您的代碼不起作用的原因已在本文中得到其他人的充分解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.