欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

.NET泛型解析(上)

【1】:泛型介紹

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括鄲城網(wǎng)站建設(shè)、鄲城網(wǎng)站制作、鄲城網(wǎng)頁(yè)制作以及鄲城網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,鄲城網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到鄲城省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

泛型是C#2.0中一個(gè)重要的新特性,泛型是CLR和編程語(yǔ)言提供的一種特殊機(jī)制,它支持另一種形式的代碼重用。

泛型誕生之前:

C#是一種強(qiáng)類型的語(yǔ)言,在沒(méi)有泛型沒(méi)有被提出之前,我們?cè)谑褂眉系拇a的時(shí)候,每次對(duì)其進(jìn)行轉(zhuǎn)換都需要隱式的強(qiáng)制轉(zhuǎn)換,我們都知道所有對(duì)象的最終基類是object,我們?cè)诿看问褂胦bject的時(shí)候,無(wú)論是變換什么類型都要對(duì)其進(jìn)行強(qiáng)制轉(zhuǎn)換。

一般情況下,創(chuàng)建泛型類的過(guò)程為:從一個(gè)現(xiàn)有的具體類開(kāi)始,逐一將每個(gè)類型更改為類型參數(shù),直至達(dá)到通用化和可用性的最佳平衡。 創(chuàng)建您自己的泛型類時(shí),需要特別注意以下事項(xiàng):

  • 將哪些類型通用化為類型參數(shù)。

    通常,能夠參數(shù)化的類型越多,代碼就會(huì)變得越靈活,重用性就越好。 但是,太多的通用化會(huì)使其他開(kāi)發(fā)人員難以閱讀或理解代碼。

  • 如果存在約束,應(yīng)對(duì)類型參數(shù)應(yīng)用什么約束

    一條有用的規(guī)則是,應(yīng)用盡可能最多的約束,但仍使您能夠處理必須處理的類型。 例如,如果您知道您的泛型類僅用于引用類型,則應(yīng)用類約束。 這可以防止您的類被意外地用于值類型,并允許您對(duì) T 使用 as 運(yùn)算符以及檢查空值。

  • 是否將泛型行為分解為基類和子類。

    由于泛型類可以作為基類使用,此處適用的設(shè)計(jì)注意事項(xiàng)與非泛型類相同。 請(qǐng)參見(jiàn)本主題后面有關(guān)從泛型基類繼承的規(guī)則。

  • 是否實(shí)現(xiàn)一個(gè)或多個(gè)泛型接口。

    例如,如果您設(shè)計(jì)一個(gè)類,該類將用于創(chuàng)建基于泛型的集合中的項(xiàng),則可能必須實(shí)現(xiàn)一個(gè)接口,如 IComparable,其中 T 是您的類的類型。

【2】:泛型的表示方式

泛型可以為引用類型和值類型還有接口和委托,F(xiàn)CL( DLL程序集包含了.NET框架下的各種DLL )類中定義了一個(gè)泛型列表,用來(lái)管理一個(gè)對(duì)象集合,如果我們想要使用這個(gè)泛型列表,可以在使用時(shí)指定具體數(shù)據(jù)類型。

泛型的表示為 “T” 如:List<T>, T 表示一個(gè)未指定的數(shù)據(jù)類型,我們可以看一下FCL類中泛型的引用定義:

【3】:泛型的好處

1 : 使代碼更加的簡(jiǎn)潔,清晰

 從前面我們也提到了,泛型具備可重用性 , 減少我們代碼量, 使我們的程序更容易開(kāi)發(fā)和維護(hù),舉例 :

 舉例 1 : 在從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)庫(kù)的時(shí)候,我們經(jīng)常會(huì)返回一個(gè)DataTable類型,然后將其轉(zhuǎn)換為L(zhǎng)ist集合. 那么如果沒(méi)有泛型的話,我會(huì)一般會(huì)這樣來(lái)做.

public List<TrainingUser> GetTrainingUser(string userId)
        {
            DataTable dt =
                     SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,
                        @"
                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU
                        INNER JOIN [USER] AS U
                         ON U.ID = TU.USERID 
                        JOIN [TRAINING] AS T
                        ON T.ID = TU.TRAININGID
                        WHERE U.ID = '"+userId+"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0];
            return DataTableToList(dt);
        }

        private List<TrainingUser> DataTableToList(DataTabledt)
        {
            List<TrainingUser> list = new List<TrainingUser>();
            if(dt. Rows.Count > 0 )
            {
                foreach (DataRow row in dt .Rows)
                {
                    TrainingUser trainingUser = new TrainingUser();
                    if(row["UserId" ] != null)
                    {
                        trainingUser .UserId = row["UserId"].ToString();
                    }
                    if(row["TrainingId" ] != null)
                    {
                        trainingUser.TrainingId = row["TrainingId"].ToString();
                    }
                    list.Add(trainingUser);
                }
            }
            return list;
        }


在方法DataTableToList中,我們傳入了一個(gè)DataTable的對(duì)象,然后在去循環(huán)遍歷每一行的對(duì)象值從而去賦值給TrainingUser類型對(duì)象,這只是其中的一個(gè)方法,如果我們的類型還有 Training/User/Project等類型的話,我們是不是就要寫很多如同DataTableToList這樣的方法呢? 這就體現(xiàn)出了這樣的方式,會(huì)造成代碼的冗余以及維護(hù)不便問(wèn)題,那么我們使用泛型來(lái)解決

舉例 2 : 使用泛型使上面的代碼更見(jiàn)的清晰,簡(jiǎn)潔

 public static List<T> ToList1<T>(DataTable dt) whereT : class, new()
        {
            var prlist =new List<PropertyInfo>();
            Type type = typeof(T);
            Array.ForEach(
                type.GetProperties(),
                p =>
                {
                    if(dt.Columns.IndexOf(p.Name) !=-1)
                    {
                        prlist.Add(p);
                    }
                });
            var oblist = new List<T>();
            // System.Data.SqlTypes.
            foreach(DataRow row in dt.Rows)
            {
                var ob = new T();
                prlist.ForEach(
                    p =>
                    {
                        if(row[p.Name] != DBNull.Value)
                        {
                            p.SetValue(ob, row[p.Name], null);
                        }
                    });
                oblist.Add(ob);
            }
            return oblist;
        }

在上面的這個(gè)方法中,我們定義了一個(gè)泛型方法,內(nèi)部實(shí)現(xiàn)中是使用了反射的原理,將DataTable轉(zhuǎn)換為了List(反射后續(xù)隨筆中總結(jié),此處只關(guān)注泛型部分即可),我們定義了一個(gè)靜態(tài)的返回值為L(zhǎng)ist<T> ,前面我們說(shuō)過(guò) T : 代表任意類型(枚舉除外),ToList1<T>,說(shuō)明我們?cè)谡{(diào)用這個(gè)方法的時(shí)候,同時(shí)要賦予方法名一個(gè)類型值,這個(gè)類型要和它的返回值類型一致(泛型是類型安全的),Where : 用于限制T的條件 ,例如 where T : class,new() 表示 T 只能是一個(gè)類,或者一個(gè)類型對(duì)象,那么我們?cè)谡{(diào)用的時(shí)候就可以這樣來(lái) 

public List<TrainingUser>GetTrainingIdByUserId(string userId)
        {
              List<TrainingUser> trainingUserList =  DataTableHelper.ToList1<TrainingUser>(
                    SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,
                        @"
                        SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU
                        INNER JOIN [USER] AS U
                         ON U.ID = TU.USERID 
                        JOIN [TRAINING] AS T
                        ON T.ID = TU.TRAININGID
                        WHERE U.ID = '"+ userId +"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[0]);
              return trainingUserList ;
        }

代碼中的DataTableHelper.ToList1<TrainingUser> 即為我們剛才所寫的一個(gè)泛型方法,這樣我們可以看到,ToList<T> 傳入的類型為TrainingUser,同時(shí)接收者為:List<T> = List<TrainingUser> , 

這樣即便我們后續(xù)還有Training/User/Project等其他的類型,我們都可以直接使用DataTableHelper.ToList1<T>(DataTable dt) 來(lái)進(jìn)行類型轉(zhuǎn)換.

2 : 提升程序的性能

泛型與非泛型相比較而言,性能要好一些,這是為什么? 首先,泛型的類型是由調(diào)用者(接收者),去直接賦值的(類型安全的), 那么就不會(huì)存在類型轉(zhuǎn)換的問(wèn)題,其次, 泛型減少了裝箱和拆箱的過(guò)程.

實(shí)例 3 : 對(duì)于值類型泛型與非泛型的性能比較

        private static void ListTest()
        {
            List<int>list = new List<int>();
            for(inti = 0; i < 100; i++)
            {
                list.Add(i);
                int a = list[i];
            }
            list =null;
        }
        private static void ArrListTest()
        {
            ArrayList arr = new ArrayList();
            for(inti = 0; i <100; i++)
            {
                arr.Add(i);
                int s = (int)arr[i];
            }
            arr = null;
        }
             Stopwatch sw = new Stopwatch();
            sw.Start();
            ListTest();
            Console.WriteLine(" 使用泛型List執(zhí)行值類型方法歷時(shí) :  "+ sw.Elapsed.ToString());
            sw.Stop();
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            ArrListTest();
            Console.WriteLine(" 使用非泛型ArrayList執(zhí)行值類型方法歷時(shí) :  "+ sw1.Elapsed.ToString());
            sw1.Stop();
            Console.ReadLine();

通過(guò)循環(huán) 100 來(lái)比較,結(jié)果為 : 

.NET泛型解析(上)

我們可以看到非泛型的時(shí)間要比泛型的時(shí)間多出0.0000523秒,泛型比非泛型的時(shí)間要多出一些, 那么我們將數(shù)值改動(dòng)一下改為循環(huán) 1000次.得出結(jié)果為 : .NET泛型解析(上)

泛型比非泛型執(zhí)行的時(shí)間要短0.0000405秒

我們將時(shí)間在改動(dòng)一下,改為 100000呢?結(jié)果為 : 

.NET泛型解析(上)

這次差距為 0.0054621 并且隨著執(zhí)行次數(shù)的增長(zhǎng),非泛型相比泛型的時(shí)間會(huì)逐步的增加,

通過(guò)反編譯我們也能看出 : 

泛型:

.NET泛型解析(上).NET泛型解析(上)

非泛型

.NET泛型解析(上).NET泛型解析(上)

從編譯中我們也能看出泛型方法中,接收的為Int32,非泛型為Object,其次泛型不會(huì)進(jìn)行裝箱和拆箱操作,非泛型每次執(zhí)行都要進(jìn)行裝箱和拆箱操作.

3 : 類型安全

在實(shí)例1 , 2 ,3 中我們都有備注說(shuō)明,泛型的發(fā)送著必須要和接收者進(jìn)行一致,否則會(huì)報(bào)異常 ,例如 :

實(shí)例 4 :

.NET泛型解析(上)

講一個(gè)泛型算法應(yīng)用于一個(gè)具體的類型時(shí),編譯器和CLR能理解開(kāi)發(fā)人員的意圖,并保證只有與指定數(shù)據(jù)類型兼容的對(duì)象才能隨同算法使用,若試圖使用不兼容類型的一個(gè)對(duì)象,會(huì)造成編譯時(shí)錯(cuò)誤,或者運(yùn)行時(shí)拋出異常,

在值類型中,泛型要比非泛型的性能高出很多,在引用類型中,泛型和非泛型的性能相差無(wú)幾,但是代碼簡(jiǎn)潔了很多。

  此篇至此,下篇主要知識(shí)點(diǎn) :

1、泛型接口

2、泛型委托

3、泛型約束(主要約束,次要約束,構(gòu)造器約束)

4、泛型類型轉(zhuǎn)型

5、泛型和反射

6、泛型和屬性

  參考資料 :

        CLR C# Via

        深入理解C#

        https://msdn.microsoft.com/zh-cn/library/sz6zd40f.aspx

        https://msdn.microsoft.com/zh-cn/library/0x6a29h7.aspx

如果你覺(jué)得本文對(duì)你有幫助的話,請(qǐng)點(diǎn)右下角的推薦,或者直接關(guān)注我,后續(xù)將不斷更新.NET解析這一系列的文章....

   溫馨提示 :  知識(shí)點(diǎn)重溫,不斷總結(jié),思考, 也是一種階段性提高,希望能幫到在讀的你.

新聞名稱:.NET泛型解析(上)
標(biāo)題來(lái)源:http://aaarwkj.com/article28/pdescp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站導(dǎo)航、響應(yīng)式網(wǎng)站動(dòng)態(tài)網(wǎng)站、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
亚洲国产成人久久综合区| 人妻中字幕出轨中文字幕| 亚洲av天堂天天天堂色| 午夜性色福利在线播放| 99热这里只有精品56| 国产精品日韩欧美久久久| 日本av天堂中文字幕| 亚洲精品乱码国产妇女毛片| 中文字幕人妻丝袜一区一三区| 二区三区成人在线观看| 中文字幕人妻日韩在线| 亚洲国产精品中文字幕一区久久| 在线看电影亚洲一区| 色婷婷亚洲一区二区三区| 精品久久一区麻豆香蕉| 亚洲码欧美码一区二区三区| 欧美精品国产亚洲另类| 色婷婷丝袜一区网站| 欧美曰韩国内精品中文| 国产一级内射视频免费观看| 妇女人妻丰满少妇中文字幕| 亚洲中文字幕在线乱码| 操你啦夜夜操狠狠躁天天爽| 久久免费看少妇高潮av| 国产国产成年年人免费看片| 青青草针对华人在线视频| 日本成人一区二区在线播放| 国产经典三级在线看| 国内精品免费视频不卡| 日韩一二卡在线观看视频| 国产精品毛片在线看不卡| 小黄片免费在线播放观看| 成人免费大片在线观看视频| 求个手机免费在线观看av网址| 亚洲精品国产第一区第二区| 日韩大片一区二区三区在线观看 | 国产成人自拍激情视频| 曰韩av毛片在线观看| 免费亚洲网站在线观看视频| 欧美日韩国产一区二区的| 欧美在线观看日韩精品|