This article discusses the conversion of nullable value types (nullable<t>), but exactly how to convert a type of value object to the appropriate nullable value. It comes from a small problem that one of our members encountered today, and I've been through some sort of writing this article. Although there is no technical content to speak of, but also hope that some readers to bring help.
Directory
One or four typical conversion modes for value types
Second, when type conversion encounters nullable<t>
Third, the nullable<t>-based type conversion is implemented in the extension method
Iv. further perfecting the extension method ConvertTo
V. Talk about Nullabletypeconverter
One or four typical types of conversion methods
For type conversions, or further, for conversions between native types such as int, Double, DateTime, string, we have four typical conversions. If there is no hermit transformation relationship store between types, we can explicitly convert between types by type conversion operators, such as:
1:double Doublevalue = 3.14159265;
2:int intvalue = (int) doublevalue;
The second is the use of the static type ChangeType or ToXxx method of convert (XXX represents the target type of the conversion), such as:
1:string Literalvalue = "123";
2:int intValue1 = Convert.ToInt32 (Literalvalue);
3:int intValue2 = (int) convert.changetype (Literalvalue, typeof (int));
The third method is to create a typeconverter or a number of subclasses based on a specific type, such as Stringconverter, BooleanConverter, Datetimeconverter, and so on. When using, you need to instantiate the corresponding TypeConverter, and then call the appropriate type conversion method. Like what:
1:string literalvalue = "1981-08-24";
2:datetimeconverter datetypeconverter = new Datetimeconverter ();
3:datetime Datetimevalue = (DateTime) datetypeconverter.convertfromstring (Literalvalue);
5:literalvalue = "02:40:50";
6:timespanconverter timespanconverter = new Timespanconverter ();
7:timespan timespanvalue = (TimeSpan) timespanconverter.convertfromstring (Literalvalue);
The last common method is to convert a formatted string based on a specific type into a corresponding type, and we can invoke a concrete type of static method, parse, or tryparse to implement the type of conversion, such as:
1:string literalvalue = "1981-08-24";
2:datetime dateTimeValue1 = DateTime.Parse (Literalvalue);
3:datetime dateTimeValue2;
4:if (Datetime.tryparse (Literalvalue, out dateTimeValue2))
6: //...
7:}
second, when type conversion encounters nullable<t> type
Convert almost implements conversions between all compatible types, or it can parse a string that has a valid format, just like the parse method. However, if the target type is replaced by the nullable<t> type, the type conversion will fail. For example, we will change the target type of the second example from int to int? (nullable<int32>):
1:string Literalvalue = "123";
2:try
3: {
4: int? intvalue = (int?) Convert.changetype (Literalvalue, typeof (Int.));
5:}
6:catch (InvalidCastException ex)
7: {
8: Console.WriteLine (ex. Message);
9:}
Type conversion error messages are output:
1:invalid cast from ' System.String ' to ' system.nullable ' 1[[system.int32, mscorlib,
2: version=4.0.0.0, Culture=neutral, publickeytoken=b77a5c561934e089]] '.
In fact, if you call convert's ChangeType method to convert any type of object to a nullable<t> type, the InvalidCastException exception will be thrown, even if you convert the T type to Nullable<t >. For example, we will replace the above example with the original data type int type:
1:int intValue1 = 123;
2:try
3: {
4: int? intvalue = (int?) Convert.changetype (IntValue1, typeof (Int.));
5:}
6:catch (InvalidCastException ex)
7: {
8: Console.WriteLine (ex. Message);
9:}
A similar error message is still entered:
1:invalid cast from ' System.Int32 ' to ' system.nullable ' 1[[system.int32, mscorlib,
2:version=4.0.0.0, Culture=neutral, publickeytoken=b77a5c561934e089]] '.
In fact, objects of type T can be explicitly or implicitly converted to nullable<t> objects. In other words, the type conversions represented by the following code are not problematic:
1:int intValue1 = 123;
2:int? IntValue2 = intValue1;
3:int? IntValue3 = (int?) intValue1;
third, the nullable<t>-based type conversion is implemented in the extension method
From the above, we can conclude that if the type T1 and T2 are compatible, we can convert the T1 type object to a T2 type by using convert and then further convert to nullable<t2> by explicit type conversion. These two steps allow us to implement conversions for the nullable<t> type. For ease of operation, I write this transformation logic in an extension method for the IConvertible interface:
1:public Static Class Convertionextensions
2: {
3: Public static T? Convertto<t> (this iconvertible convertiblevalue) where t:struct
4: {
5: if (null = = Convertiblevalue)
6: {
7: return null;
8: }
9: return (T?) Convert.changetype (Convertiblevalue, typeof (T));
Ten: }
11:}
With this extension method ConvertTo, the conversion to the target type nullable<t> is straightforward:
1:int? Intvalue = "123". Convertto<int> ();
2:double? Doublevalue = "123". Convertto<double> ();
3:datetime? Datetimevalue = "1981-08-24". Convertto<datetime> ();
Iv. Further perfecting the extension method ConvertTo
The extension method defined above can only complete conversions for the target type nullable<t>. Now let's refine it further so that this method can implement conversions between any type. Here is the definition of our new version of the ConvertTo method:
1:public static T convertto<t> (this iconvertible convertiblevalue)
2: {
3: if (null = = Convertiblevalue)
4: {
5: return Default (T);
6: }
8: if (!typeof (T). Isgenerictype)
9: {
Ten: return (t) Convert.changetype (Convertiblevalue, typeof (T));
One: }
: 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));
21:}
In the above method, we first need to determine whether the target type is NULLABLE<T>, which can be judged by invoking the GetGenericTypeDefinition method of the Type object. If it is, it is first converted to the corresponding base type (nullable<t> 's generic type). We can obtain this basic type (underlying type) by invoking the static method Getunderlyingtype of the static class nullable. With this perfect version of the ConvertTo extension method, we can do any type conversions-whether the target type is a nullable value type or a non-nullable value type:
1:int intValue1 = "123". Convertto<int> ();
2:int? IntValue2 = "123". Convertto<int?> ();
3:datetime dateTimeValue1 = "1981-08-24". Convertto<datetime> ();
4:datetime? DateTimeValue2 = "1981-08-24". Convertto<datetime?> ();
v. Talk about Nullableconverter
It talks about the TypeConverter type, and says it has a series of subclasses for specific data types. One of the subcategories is nullableconverter, hence the name meaning, this typeconverter is specifically used for nullable<t> type conversions. It is convenient to use this class for conversions of nullable value types, such as:
1:string literalvalue = "1981-08-24";
2:nullableconverter converter = new Nullableconverter (typeof (DateTime));
3:datetime? Datetimevalue = (DateTime?) Converter. ConvertFromString (Literalvalue);
Article source: Talk about the type conversion problem of nullable<t>
Discussion on the type conversion of nullable<t>