. Net to determine whether an object is a numerical type. Summary (high nutrition content, including final code and running points),. net Value
After the previous article was published, it triggered a positive discussion and played a leading role. Thank you for your participation.
Excuse me: this problem is much harder than it looks.
There is still no correct answer to the discussion, but I have summarized a code that is similar to the final version based on the discussion results. I will share it here. After all, this is the collective wisdom of everyone, without communication and collision, there is no such code.
Contribution nomination ceremony
Thank you for your patience !~~ NETRUBE proposed the method of using GetTypeCode () to obtain the type code. This method has higher performance than typeof (), but it has some limitations and will be pointed out later in the code.
(Maybe not always) the final version of the Code (or not)
In addition to the improvement of the above problems, we also re-adjusted it to three methods to determine whether it is a numerical type, a value type that can be empty, and a value type that can be empty.
/// <Summary> /// determines whether the data type is Numeric. /// </Summary> /// <param name = "t"> type to be determined </param> /// <returns> whether it is a numerical value </returns> public static bool IsNumericType (this Type t) {var tc = Type. getTypeCode (t); return (t. isPrimitive & t. isValueType &&! T. IsEnum & tc! = TypeCode. Char & tc! = TypeCode. Boolean) | tc = TypeCode. Decimal;} // <summary> // determines whether the value type is null. /// </Summary> /// <param name = "t"> type to be determined </param> /// <returns> whether it is a null value </returns> public static bool IsNumericOrNullableNumericType (this Type t) {return t. isNumericType () | (t. isNullableType () & t. getGenericArguments () [0]. isNumericType ();} // <summary> // determines whether the data type is null. /// Note: directly calling the. GetType () method of an empty object will return the actual type of its generic value. If you use this method, false is returned. /// </Summary> /// <param name = "t"> type to be determined </param> /// <returns> whether the type is null </returns> public static bool IsNullableType (this Type t) {return t. isGenericType & t. getGenericTypeDefinition () = typeof (Nullable <> );}
Code for testing designed to exhaust computers
This test code can be run successfully, basically covering common types.
[TestClass] public class BasicTest {[TestMethod] public void Value Type judgment test () {for (int I = 0; I <500000; I ++) {Assert. isTrue (591 ). getType (). isNumericType (); Assert. isTrue (31.131 ). getType (). isNumericType (); Assert. isTrue (31.20.f ). getType (). isNumericType (); Assert. isTrue (Int64) 31 ). getType (). isNumericType (); Assert. isTrue (new decimal (31.351 )). getType (). isNumericType (); Assert. isTrue (new Dec Imal (31.351 )). getType (). isNumericType (); Assert. isTrue (byte) 31 ). getType (). isNumericType (); Assert. isTrue (UInt64) 31 ). getType (). isNumericType (); Assert. isTrue (UIntPtr) 31 ). getType (). isNumericType (); Assert. isTrue (short) 31 ). getType (). isNumericType (); Assert. isTrue (Single) 31 ). getType (). isNumericType (); Assert. isTrue (typeof (Int64 ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (UInt64 ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (decimal ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (Decimal ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (UIntPtr ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (byte ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (Single ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (Double ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (float ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (double ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (int ?)). IsNumericOrNullableNumericType (); Assert. IsTrue (typeof (short ?)). IsNumericOrNullableNumericType (); Assert. isTrue (typeof (Nullable <Byte> )). isNumericOrNullableNumericType (); Assert. isFalse (DateTime. now. getType (). isNumericType (); Assert. isFalse (TimeSpan. fromDays (2 ). getType (). isNumericType (); Assert. isFalse ("aacc ". getType (). isNumericType (); Assert. isFalse (System. uriPartial. path. getType (). isNumericType (); Assert. isFalse ('C '. getType (). isNumericType (); Assert. is False (false. GetType (). IsNumericType (); Assert. IsFalse (typeof (DateTime ?)). IsNumericOrNullableNumericType (); Assert. IsFalse (typeof (Char ?)). IsNumericOrNullableNumericType (); Assert. IsFalse (typeof (char ?)). IsNumericOrNullableNumericType (); Assert. IsFalse (typeof (System. UriPartial ?)). IsNumericOrNullableNumericType (); Assert. IsFalse (typeof (Boolean ?)). IsNumericOrNullableNumericType (); Assert. IsFalse (typeof (bool ?)). IsNumericOrNullableNumericType ());}}}
It should be noted that:
The GetType () method is not used to obtain the type object for null type determination. Because I tested it, the original type returned by executing GetType () of the null type is still not empty, you can directly determine whether the data type is Numeric.
So why do we need to judge the null type? If you have tried ASP. net Mvc, you will know that the ModelMetadata of the model attribute returned by its ModelType attribute is the Nullable <> type. null-type judgment is used in this case.
Foreigner! Don't take a minute to run?
Return t = typeof (int) | t = typeof (double) | t = typeof (long) | t = typeof (short) | t = typeof (float) | t = typeof (Int16) | t = typeof (Int32) | t = typeof (Int64) | t = typeof (uint) | t = typeof (UInt16) | t = typeof (UInt32) | t = typeof (UInt64) | t = typeof (sbyte) | t = typeof (Single) | t = typeof (Decimal) | t = typeof (Byte) | t = typeof (UIntPtr) | t = typeof (IntPtr );
Code test results for foreigners:
Return t = typeof (Int16) | t = typeof (Int32) | t = typeof (Int64) | t = typeof (Single) | t = typeof (Double) | t = typeof (UInt16) | t = typeof (UInt32) | t = typeof (UInt64) | t = typeof (Byte) | t = typeof (Decimal) | t = typeof (SByte) | t = typeof (UIntPtr) | t = typeof (IntPtr );
Optimized version of the foreign code test results:
If (t. isEnum) return false; var tc = Type. getTypeCode (t); switch (tc) {case TypeCode. int16: case TypeCode. int32: case TypeCode. int64: case TypeCode. single: case TypeCode. double: case TypeCode. UInt16: case TypeCode. UInt32: case TypeCode. UInt64: case TypeCode. byte: case TypeCode. decimal: case TypeCode. SByte: return true; default: return t = typeof (UIntPtr) | t = typeof (IntPtr );}
The code for foreigners is improved to the test result after judgment by using TypeCode:
Lecture on tour Summary
It seems very simple, but there is such deep water behind it. Without discussion, we will never get such a result and learn so much knowledge.
There is no perfect code, and we look forward to a better one. Let's continue to discuss it here. Maybe there will be better solutions after a collision!
(Microsoft: You are so hard to understand. I will give you a property directly. Please look forward to it. net Framework v10.29 blogger's birthday is special, coding-free, Chinese passion, not cut, Director cutting, leaked Blu-ray 3D edition ......... Well, we entrust it to blizzard studio for development .)
There are a variety of data source types. The work assigned by the self-Summary (NET) instructor also tells me that the data source type also lists the common ones.
Data sources may be read from the database, text files, xml files, etc. The following are common data sources:
Xml, DataSet, and IEnumerable <T>.