. NET to determine whether an object is a numerical type discussion summary (high nutrient content, including the final code and running points)

Source: Internet
Author: User

The previous article sent out after a positive discussion, played a good effect, thank you for your participation.

Spit It out: This problem is much more difficult than it seems.

The discussion finally didn't have a completely correct answer, but I summed up an almost final version of the code according to the discussion, here to share, after all, it is common wisdom crystallization, there is no communication and collision without this code.

discussion of contribution nomination ceremony

First thanks to Peanuts! ~ ~ and Netrube the way to get the type code using GetTypeCode (), which is higher than the performance of typeof (), but with a little bit of a limitation, which is indicated in the following code.

The ValueType judgment proposed by Jtans and summer is also meaningful, but it is clear that only this judgment can determine whether it is a value type or not.

It is correct that a Decimal is a non-primitive type that is not raised by Stone Hill, and we have handled it specially in the final code.

By peanuts (why there are two of them called Peanuts!) (+﹏+) ~) The code is relatively perfect, is a more summary of the discussion results, the closest to the final version:

The question is whether the char and bool types will be treated as numeric values, and the order of judgment needs to be optimized slightly.

(perhaps probably're far off is) the final version of the code (or maybe not)

In addition to the improvement of the above problems, it is also re-adjusted to 3 methods, which are used to determine whether it is a numeric type, a nullable numeric type, and a nullable type.

/// <summary>    ///determines whether it is a numeric type. /// </summary>    /// <param name= "T" >the type to Judge</param>    /// <returns>Is a numeric type</returns>     Public Static BOOLIsnumerictype ( ThisType T) {        varTC =Type.gettypecode (t); return(t.isprimitive && t.isvaluetype &&!t.isenum && tc! = Typecode.char && TC! = Typecode.bool EAN) | | TC = =Typecode.decimal; }    /// <summary>    ///determines whether a nullable numeric type is available. /// </summary>    /// <param name= "T" >the type to Judge</param>    /// <returns>Is a nullable numeric type</returns>     Public Static BOOLIsnumericornullablenumerictype ( ThisType T) {        returnT.isnumerictype () | | (T.isnullabletype () && t.getgenericarguments () [0].    Isnumerictype ()); }    /// <summary>    ///determines whether a nullable type is available. ///Notice that you call the Nullable object directly.    The GetType () method returns the actual type of its generic value, which is definitely returned false with this determination. /// </summary>    /// <param name= "T" >the type to Judge</param>    /// <returns>Is a nullable type</returns>     Public Static BOOLIsnullabletype ( ThisType T) {        returnT.isgenerictype && t.getgenerictypedefinition () = =typeof(nullable<>); }

a test code designed for exhausting a computer

Use this test code to run through, basically covering the common types.

[TestClass] Public classbasictest {[TestMethod] Public voidValue type Judgment Test () { for(inti =0; I <500000; i++) {assert.istrue (591). GetType ().                Isnumerictype ()); Assert.istrue ((31.131). GetType ().                Isnumerictype ()); Assert.istrue ((31.131f). GetType ().                Isnumerictype ()); Assert.istrue ((Int64) to). GetType ().                Isnumerictype ()); Assert.istrue ((New decimal(31.351)). GetType ().                Isnumerictype ()); Assert.istrue ((NewDecimal (31.351)). GetType ().                Isnumerictype ()); Assert.istrue ( (byte) to). GetType ().                Isnumerictype ()); Assert.istrue ((UInt64) to). GetType ().                Isnumerictype ()); Assert.istrue ((UINTPTR) to). GetType ().                Isnumerictype ()); Assert.istrue ( ( Short) to). GetType ().                Isnumerictype ()); Assert.istrue ( (single) to). 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.isfalse (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:

Here the nullable type is judged not using the GetType () method to get the type object, because I tested, nullable type execution GetType () returned is still non-nullable original type, directly to determine whether it is a numeric type.

So why do you make judgments about nullable types? If you try to get the model properties in ASP. Modelmetadata you will know that the Modeltype property returns the Nullable<> type, and the nullable type is used for this case.

Foreigner! A part of the race?

JEFFERY you should do a test, and indeed the data is the most persuasive.

We run with the test code above, note that this is the loop 500,000 rounds of testing, each round to execute the method 36 times, total execution 18 million times, we let the code run three times, take the third time results (the first pass contains the initialization process, will certainly be slower).

Our Code Test results:

It can be seen that the efficiency is quite high, the average time spent on each round: 0.016546 milliseconds, the average time to execute the method: 0.0004596111111 milliseconds

Then we took the foreigner's code to look, it does not run through this test, because the following types of it did not make a judgment: Decimal, Byte, UIntPtr.

There is a IntPtr outside of our test code.

After adding these types of judgments, the main method code is as follows:

returnt = =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);

Foreigner's Code test results:

It was duly lost to us, and the foreigner knelt to me, and those who supported the simple and rude real deal were wrong.

But wait a moment, the foreigner's code actually has some obvious repetition judgment, for example in C # typeof () obtains the int and the Int32 is actually the same, we to optimize these duplicates:

returnt = =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 Foreigner Code test results:

Ah, the foreigner still knelt to us.

We will then improve this code to use the TypeCode method to judge, which will improve some performance.

However, it is important to note:

The TypeCode obtained from the Enum type will be the corresponding Int32 type, which is not the result we want, and it needs to be judged in extra terms.

There are no IntPtr and UINTPTR entries in the TypeCode enumeration, so additional judgment is needed.

The improved Code:

if(T.isenum)return false; varTC =Type.gettypecode (t); Switch(TC) { Casetypecode.int16: CaseTypecode.int32: CaseTypecode.int64: CaseTypecode.single: Casetypecode.double: Casetypecode.uint16: CaseTypecode.uint32: CaseTypecode.uint64: CaseTypecode.byte: CaseTypecode.decimal: CaseTypecode.sbyte:return true; default:                returnt = =typeof(UINTPTR) | | t = =typeof(INTPTR); }

The foreigner's Code improvement is the test result after judging by the TypeCode way:

This effect is very good, 18 million times the magnitude, is only 81 milliseconds slower than our final code (measured three times is stably lost to our code, not floating out of the occasional floating results), this performance gap can be ignored.

This can also be seen as another final version of the code, because if you put the usual types in front of your usage environment, performance will be better (although you don't feel the difference of a few milliseconds at all), but it's unavoidable to support problems that we don't foresee, such as INTPTR and UINTPTR, in the final version of the code we gave earlier, these two types are naturally supported without a special fit.

So if you value elegance, extensibility, and coding knowledge levels, it's recommended that you use the final code I gave earlier.

Lecture on the roving summary report

Seemingly very simple problem, but there is so deep water ah, if not everyone's discussion, flatly will not get such results, and learn so much knowledge.

There is no perfect code, we look forward to the better, continue to discuss it, perhaps after the communication collision will have a better solution!

(Microsoft: Crouching trough, see you so hard force, I give you directly to do a property come out, please look forward to the. Net Framework v10.29 blogger Birthday Special uncensored Chinese passion not cut the director clip leaked Blu-ray 3D version ... Well, we entrust it to Blizzard studios for development. )

. NET to determine whether an object is a numerical type discussion summary (high nutrient content, including the final code and running points)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.