您好,登錄后才能下訂單哦!
這篇文章跟大家分析一下“如何分析Nullable<T>的類型轉換問題”。內容詳細易懂,對“如何分析Nullable<T>的類型轉換問題”感興趣的朋友可以跟著小編的思路慢慢深入來閱讀一下,希望閱讀后能夠對大家有所幫助。下面跟著小編一起深入學習“如何分析Nullable<T>的類型轉換問題”的知識吧。
下面討論可空值類型(Nullable<T>)的轉換,卻確地說是如何將一種類型的值對象轉換成相應的可空值。
一、四種典型的類型轉換方式
對于類型轉化,或者進一步地,對于像Int、Double、DateTime、String等這些原生類型之間的轉化,我們具有四種典型的轉換方式。如果類型之間不具有隱士轉換關系存儲,我們可以之間通過類型轉換操作符進行顯式轉換,比如:
double doubleValue = 3.14159265; int intValue = (int)doubleValue;
第二種則是借助于Convert這個靜態類型的ChangeType或者ToXxx方法(Xxx代表轉換的目標類型),比如:
string literalValue = "123"; int intValue1 = Convert.ToInt32(literalValue); int intValue2 = (int)Convert.ChangeType(literalValue,typeof(int));
第三種方法為創建TypeConverter或者它的基于具體類型的若干子類,比如StringConverter、BooleanConverter、DateTimeConverter等。在使用的時候你需要先實例化相應的TypeConverter,然后調用相應的類型轉換方法。比如:
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);
***一種常見的方法用在將基于某種具體類型的格式化字符串轉化成對應的類型,我們可以調用具體類型的靜態方法Parse或者TryParse實現類型的轉換,比如:
string literalValue = "1981-08-24"; DateTime dateTimeValue1 = DateTime.Parse(literalValue); DateTime dateTimeValue2; if (DateTime.TryParse(literalValue, out dateTimeValue2)) { //... }
二、當類型轉換遭遇Nullable<T>類型
Convert幾乎實現所有“兼容類型”之間的轉換,也可以向Parse方法一樣解析具有合法格式的字符串。但是,如果目標類型換成是Nullable<T>類型的時候,類型轉換將會失敗。比如我們將上面第二個例子的目標類型從int換成int?(Nullable<Int32>):
string literalValue = "123"; try { int? intValue = (int?)Convert.ChangeType(literalValue,typeof(int?)); } catch (InvalidCastException ex) { Console.WriteLine(ex.Message); }
類型轉換錯誤消息會被輸出:
Invalid cast from 'System.String' to 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'
實際上,如果你調用Convert的ChangeType方法將任何類型對象轉換成Nullable<T>類型,都會拋出出InvalidCastException異常,即使你將T類型轉化成Nullable<T>。比如,我們將上面的例子中原數據類型換成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類型的對象是可以顯式或者隱式轉化成Nullable<T>對象的。也就是說,下面代碼所表示的類型轉換是沒有問題的:
int intValue1 = 123; int? intValue2 = intValue1; int? intValue3 = (int?)intValue1;
三、將基于Nullable<T>的類型轉換實現在擴展方法中
從上面的介紹我們可以得出這樣的結論:如果類型T1和T2能夠相互兼容,我們可以借助Convert將T1類型對象轉換成T2類型,然后通過顯式類型轉換進一步轉換成Nullable<T2>。我們可以通過這兩個步驟實現針對于Nullable<T>類型的轉換。為了操作方便,我將此轉換邏輯寫在針對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,對于目標類型為Nullable<T>的轉換就顯得很簡單了:
int? intValue = "123".ConvertTo<int>(); double? doubleValue = "123".ConvertTo<double>(); DateTime? dateTimeValue = "1981-08-24".ConvertTo<DateTime>();
四、進一步完善擴展方法ConvertTo
上面定義的擴展方法只能完成針對目標類型為Nullable<T>的轉換。現在我們來進一步完善它,讓這個方法可以實現任意類型之間的轉換。下面是我們新版本的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)); }
在上面的方法中,我們首先需要確定目標類型是否是Nullable<T>,這個可以通過調用Type對象的GetGenericTypeDefinition方法來判斷。如果是,則先要將其轉換成對應的基本類型(Nullable<T>的泛型類型)。我們可以通過調用靜態類Nullable的靜態方法GetUnderlyingType來獲得這個基本類型(Underlying Type)。有了這個完善版本的ConvertTo擴展方法,我們就可以進行任意的類型轉化了——不論目標類型是可空值類型,還是非可空值類型:
int intValue1 = "123".ConvertTo<int>(); int? intValue2 = "123".ConvertTo<int?>(); DateTime dateTimeValue1 = "1981-08-24".ConvertTo<DateTime>(); DateTime? dateTimeValue2 = "1981-08-24".ConvertTo<DateTime?>();
五、談談NullableConverter
上面談到TypeConverter這個類型,并且說到它具有一系列針對具體數據類型的子類。其中一個子類就是NullableConverter,故名思義,這個TypeConverter專門用于Nullable<T>的類型轉換。使用該類實現針對可空值類型的轉換很方便,比如:
string literalValue = "1981-08-24"; NullableConverter converter = new NullableConverter(typeof(DateTime?)); DateTime? dateTimevalue = (DateTime?)converter.ConvertFromString(literalValue);
關于如何分析Nullable<T>的類型轉換問題就分享到這里啦,希望上述內容能夠讓大家有所提升。如果想要學習更多知識,請大家多多留意小編的更新。謝謝大家關注一下億速云網站!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。