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

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

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

      C#基礎(chǔ)系列——小話泛型

      前言:前面兩章介紹了C#的兩個常用技術(shù):C#基礎(chǔ)系列——反射筆記 和 C#基礎(chǔ)系列——Attribute特性使用 。這一章來總結(jié)下C#泛型技術(shù)的使用。據(jù)博主的使用經(jīng)歷,覺得泛型也是為了重用而生的,并且大部分時候會和反射一起使用。這次還是打算圍繞WWH(即What、Why、How)來講解。

       

      1、什么是泛型:通過參數(shù)化類型來實現(xiàn)在同一份代碼上操作多種數(shù)據(jù)類型。利用“參數(shù)化類型”將類型抽象化,從而實現(xiàn)靈活的復(fù)用。怎么理解呢,其實根據(jù)博主的理解,泛型就是將類型抽象化,使用抽象化的類型或?qū)ο笕崿F(xiàn)某些功能和業(yè)務(wù),然后所有需要使用這些功能和業(yè)務(wù)的具體類型去調(diào)用泛型的方法和委托。呵呵,是不是還是有點暈,別著急,我們來個例子:

      我們首先來定義一種場景:我們通過sql語句使用Ado.Net來查詢默認(rèn)得到的是弱類型的DataTable、DataReader等,而我們需要對查詢到的結(jié)果集使用lamada表達(dá)式進(jìn)行某些復(fù)雜的計算,需要將DataTable轉(zhuǎn)換為對應(yīng)的List<T>集合,首先來定義一個泛型的方法:

           public static List<T> GetListByDateTable<T>(DataTable dt)
              {
                  List<T> modelList = new List<T>();
                  try
                  {
                      //1.如果DataTable沒有數(shù)據(jù)則直接返回
                      if (dt == null || dt.Rows.Count == 0)
                      {
                          return modelList;
                      }
      
                      //2.遍歷DataTable填充實體
                      var lstCol = dt.Columns;
                      foreach (DataRow dr in dt.Rows)
                      {
                          T model = default(T);
                          //如果是object(這種一般用于一個實體類表示不了的情況),則先拼接json再反序列化為object
                          if (typeof(T).Equals(typeof(object)))
                          {
                              var strJson = "{";
                              foreach(DataColumn oCol in lstCol)
                              {
                                  var oAttrValue = Convert.IsDBNull(dr[oCol.ColumnName]) ? null : dr[oCol.ColumnName];
                                  strJson += "\"" + oCol.ColumnName + "\":\"" + oAttrValue + "\",";
                              }
                              strJson = strJson.ToString().Trim(',') + "}";
                              model = E2ERes.JavaScriptStrToObj<T>(strJson);
                          }
                          else
                          {
                              model = FillEntityByDT<T>(dt, dr);
                          }
                          modelList.Add(model);
                      }
                  }
                  catch
                  { 
                      
                  }
                  return modelList;
              }
      
              //通過DataTable填充實體類
              private static T FillEntityByDT<T>(DataTable dt, DataRow dr)
              {
                  T model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型類的實體
                  PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
                  Type type = model.GetType();
                  foreach (PropertyInfo propertyInfo in pro)
                  {
                      if (dt.Columns.Contains(propertyInfo.Name))
                      {
                          if (Convert.IsDBNull(dr[propertyInfo.Name]))
                          {
                              continue;
                          }
                          if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name])))
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, dr[propertyInfo.Name], null);
                          }
                      }
                  }
                  return model;
              }

      有了這個泛型的方法,我們在轉(zhuǎn)換DataTable和具體的List<Model>的時候是不是就是一個很好的復(fù)用。

       

      2、為什么要使用泛型:博主記得剛參加工作的前兩年有一次面試的時候就被問到“泛型有什么優(yōu)勢?”,當(dāng)時怎么回答的不記得了,只知道面試不太順利~~為什么要用泛型呢?博主覺得泛型的主要優(yōu)勢有以下幾點:

      (1)保證了類型的安全性:泛型約束了變量的類型,保證了類型的安全性。例如List<int>和ArrayList。List<int>集合只能加入int類型的變量,ArrayList可以Add任何常用類型,編譯的時候不會提示錯誤。

      (2)避免了不必要的裝箱、拆箱操作,提高程序的性能:泛型變量固定了類型,使用的時候就已經(jīng)知道是值類型還是引用類型,避免了不必要的裝箱、拆箱操作。舉例說明:

      使用泛型之前,我們使用object代替。

      object a=1;//由于是object類型,會自動進(jìn)行裝箱操作。
      
      int b=(int)a;//強(qiáng)制轉(zhuǎn)換,拆箱操作。這樣一去一來,當(dāng)次數(shù)多了以后會影響程序的運(yùn)行效率。

      使用泛型之后

      public static T GetValue<T>(T a)
      
      {
        return a;
      }
      
      public static void Main()
      
      {
        int b=GetValue<int>(1);//使用這個方法的時候已經(jīng)指定了類型是int,所以不會有裝箱和拆箱的操作。
      }

      (3)提高方法、算法的重用性。上面的例子基本能說明這個優(yōu)勢。

       

      3、泛型的使用:

      (1)泛型方法的使用:這也是博主使用最多的用法之一,像這種泛型方法一般是一些static的通用方法,例如原來項目中用到的一個將DataGridViewRow對象轉(zhuǎn)換成對應(yīng)的實體Model的方法如下:

           public static T ToObject<T>(DataGridViewRow item) where T:class
              {
                  var model = item.DataBoundItem as T;
                  if (model != null)
                      return model;
                  var dr = item.DataBoundItem as System.Data.DataRowView;
                  model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型類的實體
                  PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
                  Type type = model.GetType();
                  foreach (PropertyInfo propertyInfo in pro)
                  {
                      if (Convert.IsDBNull(dr[propertyInfo.Name]))
                      {
                          continue;
                      }
                      if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name])))
                      {
                          var propertytype = propertyInfo.PropertyType;
                          if (propertytype == typeof(System.Nullable<DateTime>) || propertytype == typeof(DateTime))
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, Convert.ToDateTime(dr[propertyInfo.Name]), null);
                          }
                          else if (propertytype == typeof(System.Nullable<decimal>) || propertytype == typeof(decimal))
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, Convert.ToDecimal(dr[propertyInfo.Name]), null);
                          }
                          else if (propertytype == typeof(System.Nullable<int>) || propertytype == typeof(int))
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, Convert.ToInt32(dr[propertyInfo.Name]), null);
                          }
                          else if (propertytype == typeof(System.Nullable<double>) || propertytype == typeof(double))
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, Convert.ToDouble(dr[propertyInfo.Name]), null);
                          }
                          else
                          {
                              type.GetProperty(propertyInfo.Name).SetValue(model, dr[propertyInfo.Name], null);
                          }
                      }
                  }
                  return model;
              }

      使用泛型方法的注意事項:

      • 泛型方法的重載:public void Fun1<T>(T a);和public void Fun1<U>(U a);是無法重載的,這其實很好理解,因為T和U其實都是泛型的一個代表符號而已;
      • 泛型方法的重寫:下面的方法重寫FuncA的重寫是正確的,F(xiàn)uncB的重寫不正確,因為約束被默認(rèn)繼承,不用再寫。
      abstract class BaseClass
      {
          public abstract T FuncA<T,U>(T t,U u) where U:T;
          public abstract T FuncB<T>(T t) where T:IComparable;
      }
       
      class ClassA:BaseClass
      {
          public override X FuncA<X,Y>(X x,Y y){...}
          public override T FuncB<T>(T t) where T:IComparable{...}
      }

       

      (2)泛型類的使用:

      public class Class_Base<DTO, T>
      {}

      使用這個類的時候必須要指定兩個泛型類。

       

      (3)泛型接口以及泛型繼承的使用:

      泛型接口的類型參數(shù)要么已實例化,要么來源于實現(xiàn)類聲明的類型參數(shù)

      public interface Interface_Base<T>
      {}
      
      public class Class_Base<DTO, T> : Interface_Base<DTO>
      {}

      DTO來源于實現(xiàn)類Class_Base

       

      (4)泛型委托的使用:其實這種用法博主真的用得很少,只是原來見到過大牛們類似的代碼。

      定義泛型委托:

      public delegate void MyDelegate<T>(T obj);

      泛型委托的使用:

      public delegate void MyDelegate<T>(T obj);
      static void Main(string[] args)
      {
          var method = new MyDelegate<int>(printInt);
          method(1);
          Console.ReadKey();
      }
      static void printInt(int i)
      {
          Console.WriteLine(i);
      }

       

      (5)泛型約束:用來約束泛型類型有那些特性。常見的泛型約束也就那么幾類:

      泛型約束的格式

      public class Imps_Base<DTO, T> : Ifs_Base<DTO>
              where T : BaseEntity
              where DTO : class
          {
        }

       

      約束說明

      T:struct

      類型參數(shù)必須是值類型。可以指定除 Nullable 以外的任何值類型。

      T:class

      類型參數(shù)必須是引用類型,包括任何類、接口、委托或數(shù)組類型。

      T:new()

      類型參數(shù)必須具有無參數(shù)的公共構(gòu)造函數(shù)。當(dāng)與其他約束一起使用時,new() 約束必須最后指定。

      T:<基類名>

      類型參數(shù)必須是指定的基類或派生自指定的基類。

      T:<接口名稱>

      類型參數(shù)必須是指定的接口或?qū)崿F(xiàn)指定的接口。可以指定多個接口約束。約束接口也可以是泛型的。

      T:U

      為 T 提供的類型參數(shù)必須是為 U 提供的參數(shù)或派生自為 U 提供的參數(shù)。這稱為裸類型約束.

      posted @ 2015-07-24 11:28  懶得安分  閱讀(8445)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美成人综合久久久| 日本一区三区高清视频| 一本久道久久综合中文字幕 | 欧产日产国产精品精品| 亚洲精品第一国产综合精品| 99精品久久免费精品久久| 婷婷六月天在线| 亚洲欧美精品一中文字幕| 武汉市| 熟女亚洲综合精品伊人久久 | 九九热在线精品视频99| 国产欧美日韩一区二区加勒比| 亚洲国产精品一区二区第一页| 蜜臀av日韩精品一区二区| 亚洲AV日韩精品久久久久| 丰满的少妇一区二区三区| 人妻少妇偷人精品免费看| 国产成人一区二区三区免费| 成年入口无限观看免费完整大片| 日韩精品中文字幕第二页| 亚洲大尺度无码专区尤物| 98精品全国免费观看视频| 亚洲精品美女一区二区| 蜜臀精品一区二区三区四区| 日本视频高清一区二区三区| 免费一级黄色好看的国产| 起碰免费公开97在线视频| 视频一区二区三区四区久久| 国产欧美日韩精品丝袜高跟鞋| 制服 丝袜 亚洲 中文 综合| 国内自拍视频一区二区三区| 精品国产AⅤ无码一区二区 | 波多野结衣无内裤护士| 夜夜爽77777妓女免费看| 又大又硬又爽免费视频| 亚洲欧美日本久久网站| 亚洲国产成人资源在线 | 狠狠色丁香婷婷亚洲综合| 国产综合久久久久鬼色| 精品国产免费一区二区三区香蕉| 沅江市|