溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何分析Nullable<T>的類型轉(zhuǎn)換問題

發(fā)布時間:2022-01-11 13:44:16 來源:億速云 閱讀:147 作者:柒染 欄目:編程語言

這篇文章跟大家分析一下“如何分析Nullable<T>的類型轉(zhuǎn)換問題”。內(nèi)容詳細(xì)易懂,對“如何分析Nullable<T>的類型轉(zhuǎn)換問題”感興趣的朋友可以跟著小編的思路慢慢深入來閱讀一下,希望閱讀后能夠?qū)Υ蠹矣兴鶐椭O旅娓【幰黄鹕钊雽W(xué)習(xí)“如何分析Nullable<T>的類型轉(zhuǎn)換問題”的知識吧。

下面討論可空值類型(Nullable<T>)的轉(zhuǎn)換,卻確地說是如何將一種類型的值對象轉(zhuǎn)換成相應(yīng)的可空值。

一、四種典型的類型轉(zhuǎn)換方式

對于類型轉(zhuǎn)化,或者進(jìn)一步地,對于像Int、Double、DateTime、String等這些原生類型之間的轉(zhuǎn)化,我們具有四種典型的轉(zhuǎn)換方式。如果類型之間不具有隱士轉(zhuǎn)換關(guān)系存儲,我們可以之間通過類型轉(zhuǎn)換操作符進(jìn)行顯式轉(zhuǎn)換,比如:

double doubleValue = 3.14159265;  int intValue = (int)doubleValue;

第二種則是借助于Convert這個靜態(tài)類型的ChangeType或者ToXxx方法(Xxx代表轉(zhuǎn)換的目標(biāo)類型),比如:

string literalValue = "123";   int intValue1 = Convert.ToInt32(literalValue);   int intValue2 = (int)Convert.ChangeType(literalValue,typeof(int));

第三種方法為創(chuàng)建TypeConverter或者它的基于具體類型的若干子類,比如StringConverter、BooleanConverter、DateTimeConverter等。在使用的時候你需要先實例化相應(yīng)的TypeConverter,然后調(diào)用相應(yīng)的類型轉(zhuǎn)換方法。比如:

string literalValue = "1981-08-24";   DateTimeConverter dateTypeConverter = newDateTimeConverter();   DateTime dateTimeValue = (DateTime)dateTypeConverter.ConvertFromString(literalValue);   literalValue = "02:40:50";   TimeSpanConverter timeSpanConverter = new imeSpanConverter();   TimeSpan timeSpanValue = (TimeSpan imeSpanConverter.ConvertFromString(literalValue);

***一種常見的方法用在將基于某種具體類型的格式化字符串轉(zhuǎn)化成對應(yīng)的類型,我們可以調(diào)用具體類型的靜態(tài)方法Parse或者TryParse實現(xiàn)類型的轉(zhuǎn)換,比如:

string literalValue = "1981-08-24";  DateTime dateTimeValue1 = DateTime.Parse(literalValue);  DateTime dateTimeValue2;   if (DateTime.TryParse(literalValue, out dateTimeValue2))   {   //...   }

二、當(dāng)類型轉(zhuǎn)換遭遇Nullable<T>類型

Convert幾乎實現(xiàn)所有“兼容類型”之間的轉(zhuǎn)換,也可以向Parse方法一樣解析具有合法格式的字符串。但是,如果目標(biāo)類型換成是Nullable<T>類型的時候,類型轉(zhuǎn)換將會失敗。比如我們將上面第二個例子的目標(biāo)類型從int換成int?(Nullable<Int32>):

string literalValue = "123";   try   {   int? intValue = (int?)Convert.ChangeType(literalValue,typeof(int?));   }   catch (InvalidCastException ex)   {   Console.WriteLine(ex.Message);   }

類型轉(zhuǎn)換錯誤消息會被輸出:

Invalid cast from 'System.String' to 'System.Nullable`1[[System.Int32, mscorlib,   Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'

實際上,如果你調(diào)用Convert的ChangeType方法將任何類型對象轉(zhuǎn)換成Nullable<T>類型,都會拋出出InvalidCastException異常,即使你將T類型轉(zhuǎn)化成Nullable<T>。比如,我們將上面的例子中原數(shù)據(jù)類型換成int類型:

int intValue1 = 123;   try   {   int? intValue = (int?)Convert.ChangeType(intValue1,typeof(int?));   }   catch (InvalidCastException ex)   {   Console.WriteLine(ex.Message);   }

依然會輸入類似的錯誤信息:

Invalid cast from 'System.Int32' to 'System.Nullable`1[[System.Int32, mscorlib,   Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

而實際上,T類型的對象是可以顯式或者隱式轉(zhuǎn)化成Nullable<T>對象的。也就是說,下面代碼所表示的類型轉(zhuǎn)換是沒有問題的:

int intValue1 = 123;   int? intValue2 = intValue1;   int? intValue3 = (int?)intValue1;

三、將基于Nullable<T>的類型轉(zhuǎn)換實現(xiàn)在擴展方法中

從上面的介紹我們可以得出這樣的結(jié)論:如果類型T1和T2能夠相互兼容,我們可以借助Convert將T1類型對象轉(zhuǎn)換成T2類型,然后通過顯式類型轉(zhuǎn)換進(jìn)一步轉(zhuǎn)換成Nullable<T2>。我們可以通過這兩個步驟實現(xiàn)針對于Nullable<T>類型的轉(zhuǎn)換。為了操作方便,我將此轉(zhuǎn)換邏輯寫在針對IConvertible接口的擴展方法中:

public static class ConvertionExtensions   {   public static T? ConvertTo<T>(this IConvertible convertibleValue) where T : struct   {   if (null == convertibleValue)   {   return null;   }   return (T?)Convert.ChangeType(convertibleValue, typeof(T));   }   }

借助于上面這個擴展方法ConvertTo,對于目標(biāo)類型為Nullable<T>的轉(zhuǎn)換就顯得很簡單了:

int? intValue = "123".ConvertTo<int>();   double? doubleValue = "123".ConvertTo<double>();   DateTime? dateTimeValue = "1981-08-24".ConvertTo<DateTime>();

四、進(jìn)一步完善擴展方法ConvertTo

上面定義的擴展方法只能完成針對目標(biāo)類型為Nullable<T>的轉(zhuǎn)換?,F(xiàn)在我們來進(jìn)一步完善它,讓這個方法可以實現(xiàn)任意類型之間的轉(zhuǎn)換。下面是我們新版本的ConvertTo方法的定義:

public static T ConvertTo<T>(this IConvertible convertibleValue)   {   if (null == convertibleValue)   {   return default(T);   }   if (!typeof(T).IsGenericType)   {   return (T)Convert.ChangeType(convertibleValue, typeof(T));   }   else   {   Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition();   if (genericTypeDefinition == typeof(Nullable<>))   {   return (T)Convert.ChangeType(convertibleValue, Nullable.GetUnderlyingType(typeof(T)));   }   }   throw new InvalidCastException(string.Format("Invalid cast from type \"{0}\" to type \"{1}\".", convertibleValue.GetType().FullName, typeof(T).FullName));   }

在上面的方法中,我們首先需要確定目標(biāo)類型是否是Nullable<T>,這個可以通過調(diào)用Type對象的GetGenericTypeDefinition方法來判斷。如果是,則先要將其轉(zhuǎn)換成對應(yīng)的基本類型(Nullable<T>的泛型類型)。我們可以通過調(diào)用靜態(tài)類Nullable的靜態(tài)方法GetUnderlyingType來獲得這個基本類型(Underlying Type)。有了這個完善版本的ConvertTo擴展方法,我們就可以進(jìn)行任意的類型轉(zhuǎn)化了&mdash;&mdash;不論目標(biāo)類型是可空值類型,還是非可空值類型:

int intValue1 = "123".ConvertTo<int>();   int? intValue2 = "123".ConvertTo<int?>();   DateTime dateTimeValue1 = "1981-08-24".ConvertTo<DateTime>();   DateTime? dateTimeValue2 = "1981-08-24".ConvertTo<DateTime?>();

五、談?wù)凬ullableConverter

上面談到TypeConverter這個類型,并且說到它具有一系列針對具體數(shù)據(jù)類型的子類。其中一個子類就是NullableConverter,故名思義,這個TypeConverter專門用于Nullable<T>的類型轉(zhuǎn)換。使用該類實現(xiàn)針對可空值類型的轉(zhuǎn)換很方便,比如:

string literalValue = "1981-08-24";   NullableConverter converter = new NullableConverter(typeof(DateTime?));   DateTime? dateTimevalue = (DateTime?)converter.ConvertFromString(literalValue);

關(guān)于如何分析Nullable<T>的類型轉(zhuǎn)換問題就分享到這里啦,希望上述內(nèi)容能夠讓大家有所提升。如果想要學(xué)習(xí)更多知識,請大家多多留意小編的更新。謝謝大家關(guān)注一下億速云網(wǎng)站!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI