国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

別誤用IsDigit與IsNumber函數(轉)

2019-11-14 16:42:00
字體:
來源:轉載
供稿:網友

1、起因

最近發現程序中有一段控制TextBox數字輸入的代碼,相信大家都不會太陌生,如下:

void int_KeyPRess(object sender, KeyPressEventArgs e){    const char Delete = (char)8;    if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Delete)    {        e.Handled = true;    }}

乍一看,好像沒有啥問題,但是卻出現了一個bug,能夠輸入全角的數字,如:0、1、2、3等。錯誤的根源就是上面代碼中用到的IsDigit函數,于是就有了下面的一番探究,讓我們來看看IsDigit函數的真面目。

2、IsDigit函數

查閱MSDN,Char.IsDigit 方法是指示某個 Unicode 字符是否屬于十進制數字類別。通過ILSpy查看其源代碼:

[__DynamicallyInvokable]public static bool IsDigit(char c){    if (char.IsLatin1(c))    {        return c >= '0' && c <= '9';    }    return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;}

第一行的IsLatin1函數是判斷字符是0~255的函數,而全角的0、1、2、3等的Unicode編碼不在這個范圍,于是就執行了下面這句代碼:

CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;

而對于Unicode的分類中,半角的1,2,3和全角的0、1、2、3等都被歸為了DecimalDigitNumber,所以對于全角的數字,這個函數返回了true。
還有一個函數IsNumber和IsDigit功能相似,我們是否可以用它來代替呢?看下面的分析

3、IsNumber函數又是何物?

MSDN的解釋:Char.IsNumber 方法指示某個 Unicode 字符是否屬于數字類別。

這個函數的定義:

[__DynamicallyInvokable]public static bool IsNumber(char c){    if (!char.IsLatin1(c))    {        return char.CheckNumber(CharUnicodeInfo.GetUnicodeCategory(c));    }    if (char.IsAscii(c))    {        return c >= '0' && c <= '9';    }    return char.CheckNumber(char.GetLatin1UnicodeCategory(c));}
internal static bool CheckNumber(UnicodeCategory uc){    switch (uc)    {    case UnicodeCategory.DecimalDigitNumber:    case UnicodeCategory.LetterNumber:    case UnicodeCategory.OtherNumber:        return true;    default:        return false;    }}

和IsDigit函數相比有3點區別:
1)多了一個UnicodeCategory.LetterNumber類型

2)多了一個UnicodeCategory.OtherNumber類型

3)多了一個IsAscii的判斷(0~127)

很顯然IsNumber的范圍更廣了。下面列舉幾種IsNumber認為是數字的字符

UnicodeCategory.LetterNumber:Ⅰ、Ⅱ、Ⅲ

UnicodeCategory.OtherNumber:①、②、③

128~255中有哪些字符會被IsNumber認為是數字,有興趣的可以自己去測試。

測試的方法可以利用這個函數:System.Globalization.CharUnicodeInfo.GetUnicodeCategory(char c) ,返回的是一個UnicodeCategory類型,你可以看看是不是IsNumber的幾個類型就知道了。

4、結論

搞清楚了上面這兩個函數的內部實現,那么在判斷是否是ASCII數字(0~9)的時候,我們就需要注意以下幾點了。

1)不能用IsDigit和IsNumber函數判斷是否是ASCII數字,這兩個函數都有可能把ASCII以外的某些字符當做是數字。

2)盡量用這種方式判斷: c >= '0' && c <= '9'(當然也可以用正則表達式)。

3)數字判斷的嚴格性,從嚴到松依次是:

 c >= '0' && c <= '9' IsDigit IsNumber

4)修改上面的bug函數作為結束

void int_KeyPress(object sender, KeyPressEventArgs e){    const char Delete = (char)8;    if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != Delete)    {        e.Handled = true;    }}

  歡迎加群:.NET反編譯|破解 群號:183569712(請輸入驗證信息:博客園). .NET反編譯|破解 


 

引用:

  別誤用IsDigit與IsNumber函數


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 娄烦县| 云阳县| 宜兰县| 武宁县| 怀化市| 富裕县| 中超| 东莞市| 莱阳市| 措勤县| 临漳县| 北宁市| 秦皇岛市| 遂平县| 县级市| 兴国县| 锡林郭勒盟| 尼勒克县| 定边县| 修文县| 宜州市| 洞头县| 双柏县| 南木林县| 遂溪县| 香河县| 华安县| 汤阴县| 涪陵区| 溧阳市| 全椒县| 河池市| 莎车县| 沙坪坝区| 连城县| 阳曲县| 广宗县| 隆化县| 蒙城县| 德令哈市| 筠连县|