.NET知識梳理——1.泛型Generic

来源:https://www.cnblogs.com/Olive116/archive/2020/02/20/12334767.html
-Advertisement-
Play Games

1. 泛型Generic 1.1 引入泛型:延遲聲明 泛型方法聲明時,並未寫死類型,在調用的時候再指定類型。 延遲聲明:推遲一切可以推遲的。 1.2 如何聲明和使用泛型 泛型方法:方法名稱後面加上尖括弧,裡面是類型參數 類型參數實際上就是一個類型T聲明,方法就可以用這個類型T了。 如下所示: pub ...


1. 泛型Generic

1.1        引入泛型:延遲聲明

泛型方法聲明時,並未寫死類型,在調用的時候再指定類型。

延遲聲明:推遲一切可以推遲的。

1.2        如何聲明和使用泛型

泛型方法:方法名稱後面加上尖括弧,裡面是類型參數

類型參數實際上就是一個類型T聲明,方法就可以用這個類型T了。

如下所示:

public static void Show<T>(T t)

        {

            Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

        }

1.3        泛型的好處和原理

泛型方法性能跟普通方法一致,泛型聲明方法時,並未寫死類型,T是什麼類型,只有在調用的時候才知道,一個方法能滿足不同類型。

1.4        泛型類、泛型方法、泛型介面、泛型委托

1.4.1  泛型類型

一個類滿足不同類型的需求

具體如下:

public class BaseModel

    {

        public int Id { get; set; }

    }

    public class GenericClass<T>

        where T:BaseModel//為泛型基類約束

    {

 

    }

1.4.2  泛型方法

一個方法滿足不同類型的需求

具體如下:

public static void Show<T>(T t)

        {

            Console.WriteLine($"This is {typeof(CustomMethod)},paramater={t.GetType().Name},value={t}");

        }

1.4.3  泛型介面

一個介面滿足不同類型的需求

   //泛型介面

    public interface IGenericInterface<T>

    {

        public void  SayHi(T t);

}

1.4.4  泛型委托

一個委托滿足不同類型的需求

public delegate void Do<T>(T t);

1.5        泛型約束

沒有約束,泛型會很局限。主要有5中泛型的約束。如下:

1.5.1  基類約束

Where T:BaseModel

可以把BaseModel當作基類

只有該類型的對象或從該類型派生出的對象,可被用作類型參數。(密封類約束的不行,因為沒有意義。)

//基類

    public class BaseModel

    {

        public int Id { get; set; }

    }

    //泛型類

    public class GenericClass<T>

        where T:BaseModel//為泛型基類約束

    {

 

}

調用:

  GenericConstraint.Show<BeiJing>(new BeiJing());

1.5.2  引用類型約束

 

//引用類型約束

        public static T Get<T>() where T:class

        {

            return default(T);//default是關鍵字,根據類型T返回對應的預設值

        }

調用:

GenericConstraint.Get<Person>(new Person());

1.5.3  值類型約束

 

  //值類型約束

        Public static D GetD<D>() where D:struct

        {

            return default(D);

        }

調用:

GenericConstraint.GetD<int>(116);

1.5.4  無參數構造函數

 

//無參數構造函數約束

        Public static S GetS<S>()

            where S: new()//無餐構造函數約束

        {     

            return new S();

        }

調用:

GenericConstraint.GetS<Chinese>();

1.5.5  介面約束

 

//介面約束

        public static void Show2<T>(T t) where T : ISports

        {

            t.Basketball();

        }

調用:

GenericConstraint.Show2<USA>(new USA());

1.6        協變、逆變

所謂協變、逆變都是跟泛型有關的(多用在介面)。

1.6.1  協變

修飾返回值

讓右邊用子類,讓泛型用起來更方便(子類轉父類)

Out修飾,協變後只能是返回結果,不能做參數

IEnumerable<Bird> birdList=new List<Sparrow>();

  //out 協變,只能是返回結果(子類轉父類)

    public interface ICustomerListOut<out T>

    {

        T Get();

    }

 

    public class CustomerListOut<T>:ICustomerListOut<T>

    {

        public T Get()

        {

            return default(T);

        }

}

 

ICustomerListOut<Bird> list2 = new CustomerListOut<Sparrow>();

            Func<Bird> func = new Func<Sparrow>(() => null);

            IEnumerable<Bird> list3 = new List<Sparrow>();

1.6.2  逆變

修飾傳入參數

讓右邊可以用父類,讓泛型用起來更方便(父類轉子類)

In修飾,逆變後只能當作參數

//in 逆變 只能是輸入參數(父類轉子類)

    public interface ICustomerListIn<in T>

    {

        void Show(T t);

    }

    public class CustomerListIn<T>:ICustomerListIn<T>

    {

        public void Show(T t)

        {

            Console.WriteLine(t.GetType().Name);

        }

}

  //逆變

            ICustomerListIn<Sparrow> list1 = new CustomerListIn<Bird>();

            Action<Sparrow> action = new Action<Bird>((i) => { });

 

public interface IMyList<in inT,out outT>

    {

        void Show(inT t);

        outT Get();

        outT Do(inT t);

    }

 

    public class MyList<T, T1> : IMyList<T, T1>

    {

        public void Show(T t)

        {

            Console.WriteLine(t.GetType().Name);

        }

 

        public T1 Get()

        {

            Console.WriteLine(typeof(T1).Name);

            return default(T1);

        }

 

        public T1 Do(T t)

        {

            Console.WriteLine(t.GetType().Name);

            Console.WriteLine(typeof(T1).Name);

            return default(T1);

        }

    }

   IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>();

    IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>();//協變

    IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>();//逆變

IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>();//逆變+協變

1.7        泛型緩存

泛型緩存,每個類型都會生成一個不同的副本(適合不同類型需要緩存一份數據的場景)

  public class GenericCache<T>

    {

        private static string _TypeTime = "";

        static GenericCache()

        {

            Console.WriteLine("This is GenericCache 靜態構造函數");

            _TypeTime = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}";

        }

 

        public static string GetCache()

        {

            return _TypeTime;

        }

}

 

/// <summary>

    /// 字典緩存:靜態屬性常駐記憶體

    /// </summary>

    public class DictionaryCache

    {

        private static Dictionary<Type, string> _TypeTimeDictionary = null;

        static DictionaryCache()

        {

            Console.WriteLine("This is DictionaryCache 靜態構造函數");

            _TypeTimeDictionary = new Dictionary<Type, string>();

        }

        public static string GetCache<T>()

        {

            Type type = typeof(Type);

            if (!_TypeTimeDictionary.ContainsKey(type))

                _TypeTimeDictionary[type] = $"{typeof(T).FullName}_{DateTime.Now.ToString("yyyy-MM-dd HH mm:ss")}";

            return _TypeTimeDictionary[type];

        }

    }


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 擱置了幾天,工作忙的一塌糊塗,今天終於抽空來繼續看看MVC的知識。先來看看MVC的路由是如何處理的。以下為替代的路由: app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{ ...
  • 前言 通常在應用程式開發到正式上線,在這個過程中我們會分為多個階段,通常會有 開發、測試、以及正式環境等。每個環境的參數配置我們會使用不同的參數,因此呢,在ASP.NET Core中就提供了相關的環境API,方便我們更好的去做這些事情。 環境 ASP.NET Core使用ASPNETCORE_ENV ...
  • ​ 在C#8.0中,針對介面引入了一項新特性,就是可以指定預設實現,方便對已有實現進行擴展,也對面向Android和Swift的Api進行互操作提供了可能性。下麵我們來看看該特性的具體規則與實現。 一、主要應用場景: 在不破壞影響已有實現的情況下,可以添加新成員。這解決了在第三方已經大量使用了的介面 ...
  • 一文帶你瞭解 C DLR 的世界 在很久之前,我寫了一片文章 "dynamic結合匿名類型 匿名對象傳參" ,裡面我以為DLR內部是用反射實現的。因為那時候是心中想當然的認為只有反射能夠在運行時解析對象的成員信息並調用成員方法。後來也是因為其他的事一直都沒有回過頭來把這一節知識給補上,正所謂亡羊補牢 ...
  • 首先新建一個項目,名稱叫Caliburn.Micro.ActionConvertions 然後刪掉MainWindow.xaml 然後去app.xaml刪掉StartupUri這行代碼 其次,安裝Caliburn.Micro,Caliburn.Micro.Core,這兩個Nuget包,如下圖 然後新 ...
  • 先看核心代碼: public List<DataEntity> SearchShopSalesReport(DateTimeOffset? dateFrom, DateTimeOffset? dateTo,string groupBy) { var query = data.DataEntity / ...
  • 本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7928521.html,記錄一下學習過程以備後續查用。 一、引言 今天我們要講行為型設計模式的第四個模式--觀察者模式,先從名字上來看。觀察者模式可以理解為既然有“觀察者”,那肯定就有“被觀察者”了。“觀察者” ...
  • 本筆記摘抄自:https://www.cnblogs.com/PatrickLiu/p/7903617.html,記錄一下學習過程以備後續查用。 一、引言 今天我們要講行為型設計模式的第三個模式--迭代器模式,先從名字上來看。迭代是遍歷的意思,迭代器可以理解為是遍歷某某的工具,遍歷什麼呢?在軟 件設 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...