最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# TextBox 擴展方法數(shù)據(jù)驗證詳細說明

 更新時間:2013年03月17日 12:50:07   作者:  
C# TextBox 擴展方法數(shù)據(jù)驗證詳細說明,需要的朋友可以參考一下

      查看公司項目代碼時,存在這樣一個問題:winform界面上有很多信息填寫,提交后臺服務(wù)器更新,但數(shù)據(jù)的合法驗證及值的轉(zhuǎn)換卻不太敢恭維,一堆的if判斷和轉(zhuǎn)換,便想著是否能擴展個方法出來,琢磨出個思路,記錄下來與大家共同探討,有不對的地方還請大家指正。

      設(shè)計思路:
    1. 由于大部分從TextBox控件中獲取數(shù)據(jù)值,可以擴展個泛型方法出來,直接根據(jù)轉(zhuǎn)換后的數(shù)據(jù)類型獲得值,類似這樣,
      var value = this.txtSample.GetValue<int>();

    2. 可以傳入一個委托用來處理轉(zhuǎn)換失敗的操作,并重載此方法,提供一個默認的操作。

  好,下面開工:
    1. 創(chuàng)建TextBox類型的擴展方法
      引用MSDN的解釋:擴展方法使您能夠向現(xiàn)有類型“添加”方法,而無需創(chuàng)建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種特殊的靜態(tài)方法,但可以像擴展類型上的實例方法一樣進行調(diào)用。 對于用 C# 和 Visual Basic 編寫的客戶端代碼,調(diào)用擴展方法與調(diào)用在類型中實際定義的方法之間沒有明顯的差異。
      擴展方法被定義為靜態(tài)方法,但它們是通過實例方法語法進行調(diào)用的。 它們的第一個參數(shù)指定該方法作用于哪個類型,并且該參數(shù)以 this 修飾符為前綴。 僅當您使用 using 指令將命名空間顯式導(dǎo)入到源代碼中之后,擴展方法才位于范圍中。
      注意:擴展方法是在非嵌套、非泛型靜態(tài)類內(nèi)部定義的

    2. 由于轉(zhuǎn)換類型未知,但為值類型,故采用泛型方法設(shè)計,并加上strut泛型約束,由于允許自定義處理轉(zhuǎn)換失敗時的操作,故傳入一個Action委托來實現(xiàn),如下:

復(fù)制代碼 代碼如下:

public static TResult GetValue<TResult>(this TextBox textBox, Action<TextBox> failed)
            where TResult : struct
        {
            var type = typeof(TResult);
            var method = type.GetMethod("TryParse", new Type[] { typeof(string), type.MakeByRefType() });
            var parameters = new object[] { textBox.Text, default(TResult) };

            // 若轉(zhuǎn)換失敗,執(zhí)行failed
            if (!(bool)method.Invoke(null, parameters))
            {
                failed(textBox);
                throw new InvalidCastException("輸入值格式不正確,請檢查輸入值。");
            }

            return (TResult)parameters[1];
        }

       這里采用反射機制來調(diào)用類型的T.TryParse(string param, out T value),例如Int32.TryParse(string param,out Int32 value)等,需要注意的是:
       (1). GetMethod()方法,必須傳入合適的參數(shù)(要反射的方法的簽名)來確定方法唯一,例如碰到重載這種情況(比較常見),否則返回值為null,方法的簽名中,若參數(shù)帶有ref 或out 關(guān)鍵字,則Type類型需要加上.MakeByRefType(),如上。
       (2). 得到唯一的方法實例后,可以傳入相應(yīng)的參數(shù),調(diào)用Invoke方法來實現(xiàn)方法的調(diào)用,MethodInfo.Invoke(object obj, object[] parameters)方法第一個參數(shù)為反射調(diào)用該方法的對象,如果為靜態(tài)方法(比如本例),可以傳入null,第二個參數(shù)為方法的參數(shù),順序必須與方法簽名一致。
       (3). 方法參數(shù)中帶有ref和out關(guān)鍵字,獲得該值通過參數(shù)數(shù)組來獲得。如本例中:parameters[1]

    3. 定義轉(zhuǎn)換失敗操作的委托
      C#內(nèi)置封裝的委托有兩種,Action和Func委托,并有很多的重載版本,參數(shù)可以有十多個,所以不用擔心參數(shù)問題。其中Action委托無返回值,屬于Void類型,F(xiàn)unc委托具有返回值,如Func<T,TResult>,在Linq操作中比較常見,在該例中,無返回值的必要,故采用Action委托,由于需要處理轉(zhuǎn)換失敗的操作,故將TextBox作為該委托的參數(shù)里進行處理,如代碼所示,當轉(zhuǎn)換失敗時進行處理:   
                    // 若轉(zhuǎn)換失敗,執(zhí)行failed
                    if (!(bool)method.Invoke(null, parameters))
                          failed(textBox);
      在此簡單介紹下委托:委托其實是一個類型,通過反編譯工具可以看出來,當構(gòu)造委托時傳入一個方法,其實會隱形的傳入兩個參數(shù)(target,methodPtr),target參數(shù)為調(diào)用該方法的實例,若靜態(tài)方法,則為null,methodPtr為傳入方法的內(nèi)存地址(在元數(shù)據(jù)中存貯該信息),faild(textBox)表面看不太好理解,為什么一個對象后面帶一個參數(shù),其實C#編譯器為我們做了很多工作,在這里實質(zhì)為faild.Invoke(textBox),這樣看還好理解委托是個類型,通過faild的委托對象來調(diào)用該委托所注冊的方法。

    4. 創(chuàng)建重載版本:
      用lambda表達式定義默認的轉(zhuǎn)換失敗操作,如果轉(zhuǎn)換失敗,則提示信息,并全部選中和定位到該輸入框上。

復(fù)制代碼 代碼如下:

public static TResult GetValue<TResult>(this TextBox textBox, bool isShowError)
            where TResult : struct
        {
            return GetValue<TResult>(textBox, p =>
            {
                if (isShowError)
                {
                    p.Focus();
                    p.SelectAll();
                    MessageBox.Show("輸入值格式不正確,請重新輸入!",
                        "提示--值類型:" + typeof(TResult).Name,
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            });
        }

復(fù)制代碼 代碼如下:

///默認版本,調(diào)用上個重載方法

public static TResult GetValue<TResult>(this TextBox textBox)
            where TResult : struct
        {
            return GetValue<TResult>(textBox, true);
        }

5. 實驗測試:
      新建winform程序,界面如圖所示:

后臺代碼:

復(fù)制代碼 代碼如下:

private void btnConvert_Click(object sender, EventArgs e)
        {
            try
            {
                var intValue = txtInt.GetValue<int>();
                var floatValue = txtFloat.GetValue<float>();
                var dateTimeValue = txtDateTime.GetValue<DateTime>();
                var doubleValue = txtDouble.GetValue<double>();
            }
            catch (Exception) { }
        }

如果輸入值非法,則提示錯誤,如圖所示:

相關(guān)文章

  • Unity3d 使用Gizmos畫一個圓圈

    Unity3d 使用Gizmos畫一個圓圈

    這篇文章主要介紹了Unity3d 使用Gizmos畫一個圓圈的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C#中GridView動態(tài)添加列的實現(xiàn)方法

    C#中GridView動態(tài)添加列的實現(xiàn)方法

    這篇文章主要介紹了C#中GridView動態(tài)添加列的實現(xiàn)方法,涉及C#中GridView的相關(guān)使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • C#線程隊列用法實例分析

    C#線程隊列用法實例分析

    這篇文章主要介紹了C#線程隊列用法,以實例形式分析了C#線程隊列的創(chuàng)建、運行、等待、結(jié)束等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • 關(guān)于C#基礎(chǔ)知識回顧--反射(二)

    關(guān)于C#基礎(chǔ)知識回顧--反射(二)

    其實說白了,反射就是能知道我們未知類型的類型信息這么一個東西.沒什么神秘可講!反射的核心是System.Type。System.Type包含了很多屬性和方法,使用這些屬性和方法可以在運行時得到類型信息
    2013-07-07
  • C#微信公眾號開發(fā)之用戶上下文WeixinContext和MessageContext

    C#微信公眾號開發(fā)之用戶上下文WeixinContext和MessageContext

    這篇文章介紹了C#微信公眾號開發(fā)之用戶上下文WeixinContext和MessageContext,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • c# winform時鐘的實現(xiàn)代碼

    c# winform時鐘的實現(xiàn)代碼

    這篇文章主要介紹了c# winform時鐘的實現(xiàn)代碼,有需要的朋友可以參考一下
    2014-01-01
  • C#使用GZipStream解壓縮數(shù)據(jù)文件的方法

    C#使用GZipStream解壓縮數(shù)據(jù)文件的方法

    這篇文章主要介紹了C#使用GZipStream解壓縮數(shù)據(jù)文件的方法,實例分析了C#中GZipStream方法的原理與使用技巧,需要的朋友可以參考下
    2015-04-04
  • c#版在pc端發(fā)起微信掃碼支付的實例

    c#版在pc端發(fā)起微信掃碼支付的實例

    本篇文章主要介紹了c#版在pc端發(fā)起微信掃碼支付的實例,具有一定的參考價值,有興趣的可以了解一下。
    2016-11-11
  • C# WPF Image控件的綁定方法

    C# WPF Image控件的綁定方法

    這篇文章主要介紹了C# WPF Image控件的綁定方法,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • Unity中Instantiate實例化物體卡頓問題的解決

    Unity中Instantiate實例化物體卡頓問題的解決

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)離線計時器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10

最新評論

左贡县| 商河县| 陆川县| 吉隆县| 蚌埠市| 景宁| 咸丰县| 绥中县| 易门县| 广丰县| 宜兰市| 定远县| 洛川县| 塘沽区| 越西县| 泽库县| 清徐县| 四子王旗| 都安| 太谷县| 宝山区| 科技| 平陆县| 建水县| 资源县| 贵定县| 密云县| 襄垣县| 井陉县| 上饶县| 崇州市| 恩平市| 锡林浩特市| 柘城县| 金山区| 长岛县| 保靖县| 罗城| 新和县| 姜堰市| 靖州|