搜尋
首頁後端開發C#.Net教程C#泛型程式設計

C#泛型程式設計

Dec 21, 2016 pm 02:47 PM

泛型:透過參數化類型來實現在同一份程式碼上操作多種資料型別。利用「參數化類型」將型別抽象化,從而實現靈活的複用。

範例程式碼:

class PRogram

    {

        static void        int obj = 2;

            Test test = new Test(obj);

            Console.WriteLine("int:" + test.obj);

            Test test1 = new Test(obj2);

            Console.WriteLine(" String:" + test1.obj);

            Console.Read();

      T>

    {

        public T obj;

        public Test(T obj)
        public Test(T obj)

        {

            this.obj = obj;

  
    int:2

String:hello world



程式分析:

1、  Test是一個泛型類。 T是要實例化的範式類型。如果T被實例化為int型,那麼成員變數obj就是int型的,如果T被實例化為string型,那麼obj就是string類型的。

2、  根據不同的類型,上面的程式顯示出不同的數值。



C#泛型機制:

C#泛型能力有CLR在運行時支援:C#泛型程式碼在編譯為IL程式碼和元資料時,採用特殊的佔位符來表示範式類型,並用專型有的IL指令支援泛型操作。而真正的泛型實例化工作以「on-demand」的方式,發生在JIT編譯時。



看看剛才的程式碼中Main函數的元資料

.method private hidebysig static void  Main(string[] args) cil managed
point
🠎     79 (0x4f)

  .maxstack  2

  .locals init ([0] int32 obj,

              [2] string obj2,

           [3] class CSharpStudy1.Test` 1 test1)

  IL_0000:  nop

  IL_0001:  ldc.i4.2

 

  IL_0004:  newobj     instance void class CSharpStudy1.Test`1 ::.ctor(!0)

  IL_0009:  stloc.1

  IL_000a:  ldstr        ldfld      !0 class CSharpStudy1.Test`1::obj

  IL_0015:  box        [mscorlib]System.Int32

  IL_001a:  call       string [mscorlib]System.String::Concat(object,

                                                              object)

  IL_001f:  call       void [mscorlib]System.Console::WriteLine(string )

  IL_0024:  nop

  IL_0025:  ldstr      "hello world"

IL_002a:  stloc.2

  IL_002b:  ldloc.2

  IL_002c:  newobj      stloc.3

  IL_0032:  ldstr      「字符串:"

  IL_0037:  ldloc.3

  IL_0038:  ldfld      !0    字串[mscorlib]System.String::Concat(string,

字串)

  IL_0042:  呼叫void [mscorlib]System.Console::WriteLine(string)

  IL_0047:  noppah ystem.Console::Read()

  IL_004d:  流行

IL_004e:  ret

} // 方法結束Program::Main



    接下來看看測試類別中建構函數的元資料

.method .ctor(!T obj) cil Managed

{

  // 代碼大小       17 (0x11)

  .maxstack  8
🎠 id [mscorlib]System.Object::.ctor()

  IL_0006:  不

  IL_0007 :  nop

  IL_0008:  ldarg.0

  IL_0009: ¢ SharpTest1.Test`1::obj

  IL_000f:  nop

  IL_0010:  ret

} / / end of method Test`1::.ctor



1、第一輪編譯時,編譯器只為Test型別產生「泛型版」的IL程式碼與元資料-並未進行泛型類型的實例化,T在中間只充當佔位符。例如:測試類型元資料中顯示的

2、JIT編譯時,當JIT編譯器第一次遇到Test時,將用int取代「範式版」IL程式碼與元數據中的T——進行泛型類型的實例化。例如:Main函數中顯示的

3、CLR為所有類型參數為“引用類型”的泛型類型產生相同的一個代碼;但是如果類型參數為“值類型”,對每一個不同的“值類型”,CLR將表示產生一個獨立的程式碼。因為實例化一個引用類型的泛型,它在記憶體中分配的大小是一樣的,但是當實例化一個值類型的時候,在記憶體中分配的大小是不一樣的。



C#泛型特點:

1、如果實例化泛型類型的參數相同,那麼JIT 編輯器就可以重複使用該類型,因此,C# 的泛化類型能夠避免了C++ 靜態模板可能導致程式碼膨脹的問題。

2、C# 泛化類型具有豐富的引用元數據,因此C#的泛型類型可以實現強大的引用技術。

3、C#的泛型類型採用“基類、接口、構造器,值類型/引用類型”的約束方式來實現對類型參數的引用“顯示約束”,提高了類型安全的同時,也失去了基於「簽章」的隱式約束所具有的高靈活性的C++模板



C#泛型繼承:

C#除了聲明可以另外泛型類型(包括類別與結構)外,也可以在基底類別中包含泛型類型的聲明。但基底類別如果是泛型類型,它的型別或以實例化,或是來自子類別(同樣是泛型型別)宣告的型別參數,看如下型別

class C

class D :C

class E:C

class F:C

類G:C // 非法

E型別為C型別提供了U、V,所以上面說的來自子類

F型別繼承於C,個人認為看成F繼承一個可以非泛型的類

G類型為非法的,因為G類型不是泛型,C是泛型,G無法提供C泛型的實例化



泛型類型的成員:

泛型類型的成員可以使用泛型類型宣告中的型別參數。但類型參數如果沒有任何約束,則只能在該類型上使用從System.Object繼承的公有成員。如下圖:




泛型介面:

泛型介面的型別參數不是實例化,或是來自實作類別宣告的型別參數



泛型委託:

泛型委託在回傳值和參數上都應用參數類型,這些參數類型同樣可以附帶合法的限制

delegate bool MyDelegate(T value);

class MyClass

{
 .}

    static bool G(string s){...}

    static void Main()

          MyDelegate p1 = new MyDelegate( F);

    }

}



泛型方法:

1、C#泛型機制只支援「在方法宣告上包含型別參數」-即泛型方法。

2、C#泛型機制不支援在方法以外的其他成員(包括屬性、事件、索引器、建構器、析構器)的宣告上包含型別參數,但這些成員本身可以包含在泛型類型中,並使用泛型類型的型別參數。

3、泛型方法既可以包含在泛型類型中,也可以包含在非泛型類型中。



泛型方法宣告:如下

public static int FunctionName(T value){...}



泛型方法的重載:




型法的重載:




型法的重載: );

public void Function1(U a);

這樣是不能構成泛型方法的重載。因為編譯器無法確定泛型類型T和U是否不同,也就無法確定這兩種方法是否不同



public void Function1(int x);

public void Function1(int x);

這樣可以構成重載



public void Function1(T t) where T:A;

public void Function1(T t) where T:B;

這樣不能構成泛型方法這樣不能構成泛型方法這樣不能構成泛型方法的重載。因為編譯器無法確定約束條件中的A和B是否不同,也就無法確定這兩個方法是否不同



泛型方法重寫:

在重寫的過程中,抽象類別中的抽象方法的約束是預設繼承的。如下:

abstract class Base

{

    public abstract T F(T t,U u) where U:T;

 );
}



class MyClass:Base

{

    public override X F(X x,Y y){...}
 . IComparable{}

}

對於MyClass中兩個重寫的方法來說

F方法是合法的,約束被默認繼承

G方法是非法的,指定任何約束都是多餘的


G方法是非法的,指定任何約束都是多餘的


泛型限制:

1、C#泛型要求對“所有泛型類型或泛型方法的類型參數”的任何假定,都要基於“顯式的約束”,以維護C#所要求的類型安全。

2、“顯式約束”由where子句表達,可以指定“基類約束”,“接口約束”,“構造器約束”,“值類型/引用類型約束”共四種約束。

3、“明確約束”並非必須,如果沒有指定“明確約束”,範式類型參數將只能存取System.Object類型中的公有方法。例如:在開始的例子中,定義的那個obj成員變數。例如我們在開始的例子中加入一個Test1類,在它當中定義兩個公共方法Func1、Func2,如下圖:






下面就開始分析這些限制:

基類約束:

下面就開始分析這些約束:

基類約束:

下面就開始分析這些限制class A

    {

        public void Func1()

       

    {

        public void Func2()

        , T>

        where S : A

        where T : B
 
        {

//S的變因可以呼叫Func1方法

            s.Func1();

             t.Func2();

        }

    }

介面限制:

interface IA

    {

        T Func1();

    }🎠        void Func2();

    }



    inter T Func3();

    }



    class MyClass

      , IC

    {

        public MyClass(T t, V v)

        {

            //T中的物件中使用Func1🠎   //T的物件           //V的物件可稱為Func2與Func3

            v );

        }

    }

構造器約束:

class A🎠   public A()

            { }

        }🠎 

            public B(int i )

            { }

        }

      {

            T t;

                          t = new T();

            }

        }



              public void Func()

            {
 
                C d = new C ();

            }

        }

  less. in the generic type or method C

    注意:C#現在只支援無參的構造器約束

    此時由於我們為B類型寫入了一個有參構造器,使得系統不會再為B自動創建一個無參的構造器,但是如果我們將B型別中加一個無參構造器,那麼物件d的實例化就不會報錯了。 B類型定義如下:

        class B

{

            public B()

                     { }

        }

值型/引用型別:

public struct A 🠎🜠值類型/引用型態:

public struct A 🠎

        public class C where T :      public class C where T :     C c1 = new C();

        C c2 = new C();

    c2物件在編譯時錯誤:The type 'B' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or methor 'C'


總結:

1、C#的泛型能力由CLR在運行時支持,它既不同於C++在編譯時所支援的靜態模板,也不同於java在編譯器層面使用「擦拭法」支援的簡單的泛型。

2、C#的泛型支援包括類別、結構、介面、委託四種泛型類型,以及方法成員。

3、C#的泛型採用“基類,接口,構造器,值類型/引用類型”的約束方式來實現對類型參數的“顯式約束”,它不支援C++模板那樣的基於簽名的隱式約束。

 以上就是C#泛型程式設計的內容,更多相關內容請關注PHP中文網(www.php.cn)! 



陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
c#.net的持續相關性:查看當前用法c#.net的持續相關性:查看當前用法Apr 16, 2025 am 12:07 AM

C#.NET依然重要,因為它提供了強大的工具和庫,支持多種應用開發。 1)C#結合.NET框架,使開發高效便捷。 2)C#的類型安全和垃圾回收機制增強了其優勢。 3).NET提供跨平台運行環境和豐富的API,提升了開發靈活性。

從網絡到桌面:C#.NET的多功能性從網絡到桌面:C#.NET的多功能性Apr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#.NET與未來:適應新技術C#.NET與未來:適應新技術Apr 14, 2025 am 12:06 AM

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

c#.net適合您嗎?評估其適用性c#.net適合您嗎?評估其適用性Apr 13, 2025 am 12:03 AM

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。