乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      .NET開發(fā)中經(jīng)常用到的擴展方法

       小蟲子的館子 2013-07-03

      整理一下自己經(jīng)常用到的幾個擴展方法,在實際項目中確實好用,節(jié)省了不少的工作量。

      1  匿名對象轉(zhuǎn)化

      在WinForm中,如果涉及較長時間的操作,我們一般會用一個BackgroundWorker來做封裝長時間的操作,給它傳遞一個類型參數(shù)。

      var parm = new { UserId = txtUserId.Text, UserText = txtText.Text, TabIndex = tabControl.SelectedIndex, CheckUrl = urls, 
      SupportFormat = supportFormat, DeleteMHT = chkDelete.Checked, FileFormat=supportFileFormat };
      backgroundWorker.RunWorkerAsync(parm);
       

      注意到一點,我這里沒有用一個類型,而是用一個匿名類型,以節(jié)省類型的定義。這種場景經(jīng)常遇到,比如這個后臺方法需要傳三個參數(shù),那個后臺方法需要五個參數(shù),如果不用我這個方法,那你需要額外的定義二個類型,分別包含三個參數(shù)或是五個參數(shù)。

      再來看DoWork時,如何使用這個匿名方法

      private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
      {
                  #region Download 
           backgroundWorker.ReportProgress(10, string.Format("Analyst beginning......"));
           var parm = e.Argument.TolerantCast(new { UserId = string.Empty, UserText = string.Empty, TabIndex = 0, 
      CheckUrl = new List<string>(), SupportFormat = string.Empty, DeleteMHT = false, FileFormat=string.Empty});
      

      與RunWorkerAsnyc中傳遞的參數(shù)一樣,定義一個匿名類型,各屬性放默認(rèn)值,然后調(diào)用TolerantCast方法,即可得到前面?zhèn)魅氲闹怠?/p>

      這個方法很大的方便了這種使用情景:方法與方法之間需要傳遞不固定的參數(shù),但是又不愿意重新定義一個新的類型。這個方法不來自于CodeProject,我把它的代碼轉(zhuǎn)在下面,供您參考

      /// <summary>
      /// 轉(zhuǎn)換匿名類型
      /// </summary>
      /// <typeparam name="T"></typeparam>
      /// <param name="o"></param>
      /// <param name="example"></param>
      /// <returns></returns>
      public static T TolerantCast<T>(this object o, T example)
                  where T : class
              {
                  IComparer<string> comparer = StringComparer.CurrentCultureIgnoreCase;
                  //Get constructor with lowest number of parameters and its parameters
                  var constructor = typeof (T).GetConstructors(
                      BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
                      ).OrderBy(c => c.GetParameters().Length).First();
                  var parameters = constructor.GetParameters();
      
                  //Get properties of input object
                  var sourceProperties = new List<PropertyInfo>(o.GetType().GetProperties());
      
                  if (parameters.Length > 0)
                  {
                      var values = new object[parameters.Length];
                      for (int i = 0; i < values.Length; i  )
                      {
                          Type t = parameters[i].ParameterType;
                          //See if the current parameter is found as a property in the input object
                          var source = sourceProperties.Find(delegate(PropertyInfo item)
                              {
                                  return comparer.Compare(item.Name, parameters[i].Name) == 0;
                              });
      
                          //See if the property is found, is readable, and is not indexed
                          if (source != null && source.CanRead &&
                              source.GetIndexParameters().Length == 0)
                          {
                              //See if the types match.
                              if (source.PropertyType == t)
                              {
                                  //Get the value from the property in the input object and save it for use
                                  //in the constructor call.
                                  values[i] = source.GetValue(o, null);
                                  continue;
                              }
                              else
                              {
                                  //See if the property value from the input object can be converted to
                                  //the parameter type
                                  try
                                  {
                                      values[i] = Convert.ChangeType(source.GetValue(o, null), t);
                                      continue;
                                  }
                                  catch
                                  {
                                      //Impossible. Forget it then.
                                  }
                              }
                          }
                          //If something went wrong (i.e. property not found, or property isn't
                          //converted/copied), get a default value.
                          values[i] = t.IsValueType ? Activator.CreateInstance(t) : null;
                      }
                      //Call the constructor with the collected values and return it.
                      return (T) constructor.Invoke(values);
                  }
                  //Call the constructor without parameters and return the it.
                  return (T) constructor.Invoke(null);
              }
       
       

      2 集合對象上的擴展方法

      先看例子,下面的測試方法

      var @enum = new[] {1, 2, 3, 4}.AsEnumerable();
      var sum = 0;
      @enum.ForEach(n => sum  = n);
      

      這個擴展方法,可以直接在一個集合上執(zhí)行一個Lambda表達式,返回結(jié)果,相當(dāng)于有二個參數(shù)的Fun<T,T>,來看它的源代碼定義

      public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
      {
            foreach (var item in @enum) mapFunction(item);
      }

       

      3 字符串類型上的擴展方法

      這里可以做的擴展方法比較多,一個明顯的例子就是,依據(jù)String類型寫的Helper類型方法最多。

      來看一個字符串拼湊的例子,平時我們用string.Format這樣的寫法,如果用下面的擴展方法,看起來更直觀一些。

      string s = "{0} ought to be enough for {1}.";
      string param0 = "64K";
      string param1 = "everybody";
      
      string expected = "64K ought to be enough for everybody.";
      Assert.AreEqual(expected, s.FormatWith(param0, param1),

      這個擴展方法的定義也簡單,只有一行代碼

      /// <summary>
      /// Formats a string with two literal placeholders.
      /// </summary>
      /// <param name="text">The extension text</param>
      /// <param name="arg0">Argument 0</param>
      /// <param name="arg1">Argument 1</param>
      /// <returns>The formatted string</returns>
      public static string FormatWith(this string text, object arg0, object arg1)
      {
               return string.Format(text, arg0, arg1);
      }
       

      可以考慮把參數(shù)延長到任意個,改寫這個擴展方法,也只需要一行代碼皆可

      /// <summary>
      /// Formats a string with two literal placeholders.
      /// </summary>
      /// <param name="text">The extension text</param>
      /// <param name="arg0">Argument 0</param>
      /// <param name="arg1">Argument 1</param>
      /// <returns>The formatted string</returns>
      public static string FormatWith(this string text, params object[] args))
      {
               return string.Format(text, args);
      }

      另一個有用的擴展方法是字符串與枚舉類型之間的轉(zhuǎn)化,擴展方法定義如下

      /// <summary>
      /// Parses a string into an Enum
      /// </summary>
      /// <typeparam name="T">The type of the Enum</typeparam>
      /// <param name="value">String value to parse</param>
      /// <returns>The Enum corresponding to the stringExtensions</returns>
      public static T ToEnum<T>(this string value)
      {
                  return ToEnum<T>(value, false);
       }

      參考下面的例子,使用這個實用的擴展方法

      enum ProductVersion
      {
          Standard,
          Enteprise,
          Ultimate
      } 
      
      [TestMethod]
      public void StringToEnumTest()
      {
            Assert.AreEqual(ProductVersion.Standard, "Standard".ToEnum<ProductVersion>());
      }

       

      4  數(shù)字類型上的擴展方法

      我這里有一個明顯的例子是顯示容量的擴展方法,請看下面的方法組:

      /// <summary> 
      /// Kilobytes 
      /// </summary> 
      /// <param name="value"></param> 
      /// <returns></returns> 
      public static int KB(this int value)
              {
                  return value * 1024;
              }
      
      /// <summary> 
      /// Megabytes 
      /// </summary> 
      /// <param name="value"></param> 
      /// <returns></returns> 
      public static int MB(this int value)
              {
                  return value.KB() * 1024;
              }
      
      /// <summary> 
      /// Gigabytes 
      /// </summary> 
      /// <param name="value"></param> 
      /// <returns></returns> 
      public static int GB(this int value)
              {
                  return value.MB() * 1024;
              }
      
      /// <summary> 
      /// Terabytes 
      /// </summary> 
      /// <param name="value"></param> 
      /// <returns></returns> 
      public static long TB(this int value)
              {
                  return (long)value.GB() * (long)1024;
              }
      

      用起來就很輕松了,簡單的一行代碼,獲取容量的數(shù)字值

      var kb = 1.KB();
      var mb = 1.MB();
      var gb = 1.GB();
      var tb = 1.TB();

      最后一組擴展方法在計算百分比中經(jīng)常遇到,比如統(tǒng)計計算,任務(wù)完成百分比計算:

       #region PercentageOf calculations
      
              /// <summary>
              /// The numbers percentage
              /// </summary>
              /// <param name="number">The number.</param>
              /// <param name="percent">The percent.</param>
              /// <returns>The result</returns>
              public static decimal PercentageOf(this int number, int percent)
              {
                  return (decimal)(number * percent / 100);
              }
      
              /// <summary>
              /// Percentage of the number.
              /// </summary>
              /// <param name="percent">The percent</param>
              /// <param name="number">The Number</param>
              /// <returns>The result</returns>
              public static decimal PercentOf(this int position, int total)
              {
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)position / (decimal)total * 100;
                  return result;
              }
              public static decimal PercentOf(this int? position, int total)
              {
                  if (position == null) return 0;
                  
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)((decimal)position / (decimal)total * 100);
                  return result;
              }
      
              /// <summary>
              /// The numbers percentage
              /// </summary>
              /// <param name="number">The number.</param>
              /// <param name="percent">The percent.</param>
              /// <returns>The result</returns>
              public static decimal PercentageOf(this int number, float percent)
              {
                  return (decimal)(number * percent / 100);
              }
      
              /// <summary>
              /// Percentage of the number.
              /// </summary>
              /// <param name="percent">The percent</param>
              /// <param name="number">The Number</param>
              /// <returns>The result</returns>
              public static decimal PercentOf(this int position, float total)
              {
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)((decimal)position / (decimal)total * 100);
                  return result;
              }
      
              /// <summary>
              /// The numbers percentage
              /// </summary>
              /// <param name="number">The number.</param>
              /// <param name="percent">The percent.</param>
              /// <returns>The result</returns>
              public static decimal PercentageOf(this int number, double percent)
              {
                  return (decimal)(number * percent / 100);
              }
      
              /// <summary>
              /// Percentage of the number.
              /// </summary>
              /// <param name="percent">The percent</param>
              /// <param name="number">The Number</param>
              /// <returns>The result</returns>
              public static decimal PercentOf(this int position, double total)
              {
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)((decimal)position / (decimal)total * 100);
                  return result;
              }
      
              /// <summary>
              /// The numbers percentage
              /// </summary>
              /// <param name="number">The number.</param>
              /// <param name="percent">The percent.</param>
              /// <returns>The result</returns>
              public static decimal PercentageOf(this int number, decimal percent)
              {
                  return (decimal)(number * percent / 100);
              }
      
              /// <summary>
              /// Percentage of the number.
              /// </summary>
              /// <param name="percent">The percent</param>
              /// <param name="number">The Number</param>
              /// <returns>The result</returns>
              public static decimal PercentOf(this int position, decimal total)
              {
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)position / (decimal)total * 100;
                  return result;
              }
      
              /// <summary>
              /// The numbers percentage
              /// </summary>
              /// <param name="number">The number.</param>
              /// <param name="percent">The percent.</param>
              /// <returns>The result</returns>
              public static decimal PercentageOf(this int number, long percent)
              {
                  return (decimal)(number * percent / 100);
              }
      
              /// <summary>
              /// Percentage of the number.
              /// </summary>
              /// <param name="percent">The percent</param>
              /// <param name="number">The Number</param>
              /// <returns>The result</returns>
              public static decimal PercentOf(this int position, long total)
              {
                  decimal result = 0;
                  if (position > 0 && total > 0)
                      result = (decimal)position / (decimal)total * 100;
                  return result;
              }
      
              #endregion

      來看幾個測試用例,增強對它的直觀感受,因為涉及到的數(shù)值類型多一些,所以擴展方法的數(shù)量也多。

      Assert.AreEqual(33.0M, 100.PercentageOf(33));
      Assert.AreEqual(33.0M, 33.PercentOf(100));
      Assert.AreEqual(33.0M, 100.PercentageOf((float)33.0F));
      Assert.AreEqual(33.0M, 33.PercentOf((float)100.0F));
      Assert.AreEqual(33.0M, 100.PercentageOf((double)33.0F));
      Assert.AreEqual(33.0M, 33.PercentOf((double)100.0F));
      Assert.AreEqual(33.0M, 100.PercentageOf((decimal)33.0M));
      Assert.AreEqual(33.0M, 33.PercentOf((decimal)100.0M));
      Assert.AreEqual(33.0M, 100.PercentageOf((long)33));
      Assert.AreEqual(33.0M, 33.PercentOf((long)100));
      

       

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多