<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      你正確的使用Out/Ref了嗎?

      2010-12-03 19:19  空逸云  閱讀(734)  評論(6)    收藏  舉報

      最近在努力的學習MVC.并逐步的把Asp.net MVC應用到實際項目中去.先前.找了不少開源項目,心里一個高興啊.一邊摸索一邊借鑒(抄)著別人的代碼,并希望能從中吸收大牛們的思想.在CodePlex找到一個不錯的開源項目.借鑒著就著手開發了.一路上風平浪靜.抄代碼抄得起勁.不料出現了一個讓我措手不及的錯誤.該代碼實現如下.

              /// <summary>
              /// 獲取配置文件中DappSettings節點下指定索引鍵的Int類型的的值
              /// </summary>
              /// <param name="key">索引鍵</param>
              /// <param name="defaultValue">默認值</param>
              /// <returns>Int</returns>
              private static int getInt32(string key, int? defaultValue) {
                  return getValue<int>(key, (v, pv) => int.TryParse(v, out pv), defaultValue);
              }
      
              private static T getValue<T>(string key, Func<string, T, bool> parseValue, T? defaultValue) where T : struct
              {
                  string value = appSettings[key];
                  if (value != null)
                  {
                      T parsedValue = default(T);
      
                      if (parseValue(value, parsedValue))
                          return parsedValue;
                      else
                          throw new ApplicationException(string.Format("Settings '{0}' was not a valid {1}", key, typeof(T).FullName));
                  }
                  if (!defaultValue.HasValue)
                      throw new ApplicationException("在配置文件的appSettings節點結合中找不到key為" + key + "的子節點,且沒有指定默認值");
                  else
                      return defaultValue.Value;
              }

      該方法就是獲取配置文件里相關的AppSetting項,并將其轉換成Int32值.很不錯的實現.但是實際上運行的時候卻發現返回的值永遠就是0,這不對啊.于是仔細的分析了這兩個方法.主要就是利用了out關鍵字.

      我們知道,利用Out/Ref關鍵字,能使值類型的參數達到引用類型的參數的效果.

      瓦解黑盒子

      仔細分析了這兩個方法.將核心實現重現如下

          public class MyClass
          {
              static int parseValue(string str, int pv)
              {
                  if (ValidParse(str, pv))
                      return pv;
                  else
                      return 0;
              }
      
              static bool ValidParse(string str, int input)
              {
                  return Int32.TryParse(str, out input);
              }
      
      
              public static void Main()
              {
                  string str = "100";
                  int num = 0;
                  Console.WriteLine(parseValue(str, num));
              }
      
          }

      看得到.調用步驟如下Main->parseValue->ValidParse,Main得到了一個字符串變量,想把它轉換成Int類型,于是找到了parseValue方法.parseValue方法要求Main提供字符串和一個Int變量,它的做法是利用ValidParse方法,嘗試能否吧str轉換成Int,如果可以的話就返回Int,注意!此處的原意和TryParse相識.而ValidParse方法就是簡單的調用了TryParse.大體看下來.這個流程是沒什么問題的.而且應該得到正確的答案.但事實卻并非如此.圖解一下

      image

      可能圖畫得不太精確.但能詮釋這個過程就好了.調用的過程.

      第一步.看到.str是引用過去了.而num并不是原值,而是做了一個副本拷貝.這樣.即使在parseValue中num的值發生改變.也只是副本數據發生了改變.

      第二步.可以看到.str還是引用,即保持第一手數據.而num又做了一次副本拷貝.在validParse上調用了TryParse方法.此時,ValidParse上的num改變了.但是注意.此處也是副本修改.所以.

      第三步(返回),num數據丟失.這也就解釋了為什么我們的結果總會是0了.

      既然知道了原因.那就好辦了.我們嘗試著加上out

          public class MyClass
          {
              static int parseValue(string str, int pv)
              {
                  if (ValidParse(str, out pv))
                      return pv;
                  else
                      return 0;
              }
      
              static bool ValidParse(string str, out int input)
              {
                  return Int32.TryParse(str, out input);
              }
      
      
              public static void Main()
              {
                  string str = "100";
                  int num = 0;
                  Console.WriteLine(parseValue(str, num));
              }
      
          }

      改動并不大.只是在第二步中調用加入out,但是恰是這個out.讓我們的結果正確了.原因就是第三步使用的num并不是步驟二的副本.而是步驟二的數據.所以它修改了原數據,沒發生數據丟失.

      優化代碼

      精簡代碼一向是我們所追崇的.特別是.Net3.5之后的Lambda.不用的話豈不浪費.廢話不多說.我們開工

      delegate bool ParseFunc<T, S>(T T1, out S S1); 

      先聲明一個委托,注意,這里的委托中用到了out.

              private static T getOutValue<T>(string key, ParseFunc<string,T> parseValue, T? defaultValue) where T : struct
              {
                  string value = appSettings[key];
                  if (value != null)
                  {
                      T parsedValue = default(T);
      
                      if (parseValue(value, out parsedValue))
                          return parsedValue;
                      else
                          throw new ApplicationException(string.Format("Settings '{0}' was not a valid {1}", key, typeof(T).FullName));
                  }
                  if (!defaultValue.HasValue)
                      throw new ApplicationException("在配置文件的appSettings節點結合中找不到key為" + key + "的子節點,且沒有指定默認值");
                  else
                      return defaultValue.Value;
              }

      再改造一下GetValue方法.此處必須注意的是,在傳參時必須使用Out,當然.你沒用out,編譯器也不會讓你通過.最后

              public static int getInt32(string key, int? defaultValue)
              {
                  return getOutValue<int>(key, (string v, out int pv) => int.TryParse(v, out pv), defaultValue);
              }

      大功告成.這里主要是理解Lambda表達式的應用.相信你對Lambda的應用有了一個不一樣的理解了吧!

      PS:可能這個標題和文章內容有些格格不入,甚至有標題黨的感覺.沒什么文采.大家就體諒體諒.

      主站蜘蛛池模板: 国产极品美女高潮抽搐免费网站 | 亚洲精品色在线网站| 国产精品一区二区三区黄色| 精品婷婷色一区二区三区| 老熟女多次高潮露脸视频| 一区二区不卡国产精品| 欧美精品人人做人人爱视频| 亚洲天堂男人影院| 亚洲热视频这里只有精品| 久久综合伊人77777| 亳州市| 国产成人精品永久免费视频| 午夜DY888国产精品影院| 丰满人妻一区二区三区高清精品| 午夜福利伦伦电影理论片在线观看| 老司机精品影院一区二区三区| 亚洲一区二区三区18禁| 国产精品一区二区三区专区| 国产av精品一区二区三区| 国产av人人夜夜澡人人爽麻豆| 四虎影视库国产精品一区| 成人精品一区日本无码网| 婷婷丁香五月激情综合| 热久在线免费观看视频| 国产成人精品亚洲精品密奴| 久久99精品国产99久久6尤物| 精品无码一区在线观看| 欧美牲交a欧美牲交aⅴ图片| 国产成人高清亚洲一区二区| 97在线观看视频免费| 国产亚洲精品在天天在线麻豆| 好硬好湿好爽好深视频| 亚洲岛国av一区二区| 亚洲精品国产老熟女久久| 日本一区二区不卡精品| 亚洲午夜成人精品电影在线观看| 免费无码肉片在线观看| 久操热在线视频免费观看| 国产亚洲一二三区精品| 亚洲中文字幕一区二区| 中文日产幕无线码一区中文|