程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> .Net判斷一個對象是否為數值類型探討總結(高營養含量,含最終代碼及跑分),.net數值

.Net判斷一個對象是否為數值類型探討總結(高營養含量,含最終代碼及跑分),.net數值

編輯:C#入門知識

.Net判斷一個對象是否為數值類型探討總結(高營養含量,含最終代碼及跑分),.net數值


前一篇發出來後引發了積極的探討,起到了拋磚引玉效果,感謝大家參與。

吐槽一下:這個問題比其看起來要難得多得多啊。

大家的討論最終還是沒有一個完全正確的答案,不過我根據討論結果總結了一個差不多算是最終版的代碼,這裡分享出來,畢竟這是大家共同的智慧結晶,沒有交流和碰撞就沒有這段代碼。

 

探討貢獻提名典禮

首先感謝 花生!~~ 以及 NETRUBE 提出了使用 GetTypeCode() 獲取類型代碼的方式,這個比 typeof() 的性能要高,但是有一點局限性,後面代碼中會指出。

(可能也許大概差不離就是)最終版代碼(也可能不是)

除了對上述存在問題的改進,還重新調整為3個方法,分別是用來判斷是否為數值類型、可空數值類型及可空類型。

/// <summary>
    /// 判斷是否為數值類型。
    /// </summary>
    /// <param name="t">要判斷的類型</param>
    /// <returns>是否為數值類型</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>
    /// 判斷是否為可空數值類型。
    /// </summary>
    /// <param name="t">要判斷的類型</param>
    /// <returns>是否為可空數值類型</returns>
    public static bool IsNumericOrNullableNumericType(this Type t)
    {
        return t.IsNumericType() || (t.IsNullableType() && t.GetGenericArguments()[0].IsNumericType());
    }

    /// <summary>
    /// 判斷是否為可空類型。
    /// 注意,直接調用可空對象的.GetType()方法返回的會是其泛型值的實際類型,用其進行此判斷肯定返回false。
    /// </summary>
    /// <param name="t">要判斷的類型</param>
    /// <returns>是否為可空類型</returns>
    public static bool IsNullableType(this Type t)
    {
        return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

 

為了累死電腦而設計的測試用代碼

使用這個測試代碼跑可以通過,基本涵蓋了常用類型。

[TestClass]
    public class BasicTest
    {
        [TestMethod]
        public void 數值類型判斷測試()
        {
            for (int i = 0; i < 500000; i++)
            {
                Assert.IsTrue((591).GetType().IsNumericType());
                Assert.IsTrue((31.131).GetType().IsNumericType());
                Assert.IsTrue((31.131f).GetType().IsNumericType());
                Assert.IsTrue(((Int64)31).GetType().IsNumericType());
                Assert.IsTrue((new decimal(31.351)).GetType().IsNumericType());
                Assert.IsTrue((new Decimal(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.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());
            }

        }
    }

需指出的是:

這裡對可空類型判斷沒有使用 GetType() 方法獲取類型對象,因為我測試了一下,可空類型執行 GetType() 返回的仍然是不可空的原類型,直接進行判斷是否為數值類型即可。

那麼為什麼還要做針對可空類型的判斷呢?如果你試過在 ASP.Net Mvc 中獲取到模型屬性的 ModelMetadata 你就會知道,其 ModelType 屬性返回的就是 Nullable<> 類型,可空類型的判斷就是給這種情況使用的。

 

老外!不服跑個分?

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

老外的代碼測試結果:

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

優化版的老外代碼測試結果:

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); }

老外的代碼改進為用 TypeCode 方式進行判斷後的測試結果:

巡回總結報告會演講

看似非常簡單的問題,背後卻有這麼深的水啊,若沒有大家的討論,斷然不會得到這樣的成果,並且學到這麼多知識。

沒有完美的代碼,我們期待更好,在此繼續討論吧,也許交流碰撞後還會有更優秀的方案!

(微軟:臥槽,看你們這麼苦逼,我給你們直接做一個屬性出來吧,請期待.Net 框架v10.29博主生日特別無碼漢化激情未刪減導演剪輯洩露藍光3D版………嗯,我們將其委托給暴雪工作室開發。)


數據源類型有多種,自我總結(NET) 老師布置的作也解 告訴我數據源類型也行舉列一下常見的那種

數據源可能是讀取自數據庫,也可能是文本文件、xml文件等,常見的有以下幾種:
Xml、DataSet、IEnumerable<T>。
 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved