學習Linq之前必須要瞭解的擴展方法

来源:https://www.cnblogs.com/lxshwyan/archive/2019/05/05/10815731.html
-Advertisement-
Play Games

本文主要以下麵幾個方面來詳細講解擴展方法:在C#3.0之前沒有擴展方法的狀態(或者你不會使用不知道擴展方法的時候)、擴展方法的語法及怎麼使用、怎麼正確的使用擴展方法; 一、首先說一下在C#3.0之前沒有擴展方法的狀態(或者你不會使用不知道擴展方法的時候) 1、大家在項目中肯定遇到類似這樣的需求且項目 ...


      本文主要以下麵幾個方面來詳細講解擴展方法:在C#3.0之前沒有擴展方法的狀態(或者你不會使用不知道擴展方法的時候)、擴展方法的語法及怎麼使用、怎麼正確的使用擴展方法;

  一、首先說一下在C#3.0之前沒有擴展方法的狀態(或者你不會使用不知道擴展方法的時候)

        1、大家在項目中肯定遇到類似這樣的需求且項目很多地方都會用到:1.需要對一個對象進行可空判斷;2、對一個集合或者對象進行序列化;3、時間格式轉換;4、List與DataTabel之前轉換等等。

              我想在沒有擴展方法之前大家基本上都是做一個類似common的靜態公共靜態類,寫一些靜態方法供項目各個調用調用 如:

 public static  class Common
    {
        /// <summary>
        /// 判斷是否為Null或者空
        /// </summary>
        /// <param name="obj">對象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty( object obj)
        {
            if (obj == null)
                return true;
            else
            {
                string objStr = obj.ToString();
                return string.IsNullOrEmpty(objStr);
            }
        }
    }
View Code

          其他類調用公共方法

 static void Main(string[] args)
        {
            string str = "lxsh";
            Common.IsNullOrEmpty(str);
        }
View Code

        通過這樣也能完成上面所說的幾個需求,但是讓人感覺上端一直要顯示依賴Common這個靜態類,項目中就會大量充斥著這樣的代碼,看起來不那麼簡潔,而且也不利於後期的鏈式語法編程;

        2、有時也會遇到這樣的情況:你想對某個類型加一些行為(方法),但你不能改變該類型的本身,因為是別人的代碼,遇到這樣情況你可能會增加一個繼承介面,或者一個抽象類,或者通過代理模式封裝一次,這樣顯然能達到目的但都很麻煩;

          以上解決辦法都是在沒有使用擴展方法之前的解決方案,當你學會了擴展方法,你可能會有更好的選擇;

    二、 接下來我們來說一下擴展方法的語法及使用

      1、擴展方法必須具備以下幾個特征:

  •             必須是在非嵌套的、非泛型的靜態類中
  •              必須在靜態類中的靜態方法
  •             至少要有一個參數
  •             第一個參數的首碼必須加this關鍵字且不能有任何修飾符(如:ref,out)且參數類型不能為指針

 例如:

 public static partial class Extensions
    {

        public static string ObjectToJSON(this object obj)
        {
            return JsonConvert.SerializeObject(obj, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
        }
        /// <summary>
        /// 判斷是否為Null或者空
        /// </summary>
        /// <param name="obj">對象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this object obj)
        {
            if (obj == null)
                return true;
            else
            {
                string objStr = obj.ToString();
                return string.IsNullOrEmpty(objStr);
            }
        }

    }
View Code

    2、怎麼使用擴展方法:

         先引用擴展方法靜態類所在的命名空間,引用完成後,在調用的時候它在你對應類型實例上面有”智能感知“提示

 

    3、擴展方法是怎麼被髮現調用的

    如果在using命令,將擴展方法引用到代碼中,擴展方法可以像類一下不加限制地在代碼中使用。如果編譯器認為一個表達試好像要使用一個實例方法,但沒有找到與這個方法調用相容的實例方法,就會查找一個合適的擴展方法。它會檢查導入的所有命名空間和當前命名空間中所有的擴展方法,並匹配那些從表達式類型到擴展類型存在隱式轉換的擴展方法;

       簡單一句話講:編譯器首先會查看這類型(包括父類)有沒有對應的該實例方法,如果有該實例方法他就不會執行擴展方法,如果沒有它就會找對應的擴展方法執行;

       假如有一個 student類,它有一個實例方法say,再給他加一個擴展方法say

  public  class Student
    {
        public void Say()
        {
            Console.WriteLine("我是實例方法");
        }
    }


    public static class Extensions
    {
        public static void Say(this Student student)
        {
             Console.WriteLine("我是擴展方法");
        }

    }
View Code
  static void Main(string[] args)
        {
            Student student = new Student();
            student.Say();    
           
            Console.ReadKey();
        }
View Code

執行結果為:

     還有一種情況,對子類和父類同時加了一個一樣的擴展方法,且都引用了他們名詞空間,優先調用子類的擴展方法(同樣適用於介面父子關係)

  public class Person
    {  
    }
    public  class Student:Person
    {
        public void Say()
        {
            Console.WriteLine("我是實例方法");
        }
    }   

    public static class Extensions
    {
        public static void Say(this Student student)
        {
             Console.WriteLine("我是擴展方法");
        }
        public static void GetName(this Student student)
        {
            Console.WriteLine("我是子類擴展方法");
        }
        public static void GetName(this Person student)
        {
            Console.WriteLine("我是父類擴展方法");
        }

    }
View Code
  static void Main(string[] args)
        {
            Student student = new Student();
            student.Say();
            student.GetName();
            Console.ReadKey();
        }
View Code

執行結果:

三、怎麼正確的使用擴展方法(建議)

    接下來簡單講一下怎麼正確使用擴展方法:

     1.如果在項目中使用擴展方法,首先需要要項目成員都熟悉擴展方法的使用

     2.將擴展方法單獨放到一個單獨的命名空間里,可有效的防止被誤用,建議擴展方法所屬擴展類儘量用partial類(如針對Object的擴展方法命名Extensions.Object、針對string的擴展方法命名Extensions.String),方便代碼維護

 例如:Extensions.Object、Extensions.String

namespace Lucky.Proect.Core.Extensions
{
    public static partial class Extensions
    {

        public static string ObjectToJSON(this object obj)
        {
            return JsonConvert.SerializeObject(obj, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
        }
        /// <summary>
        /// 判斷是否為Null或者空
        /// </summary>
        /// <param name="obj">對象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this object obj)
        {
            if (obj == null)
                return true;
            else
            {
                string objStr = obj.ToString();
                return string.IsNullOrEmpty(objStr);
            }
        }

    }
}
View Code

 

namespace Lucky.Proect.Core.Extensions
{
   public static partial   class Extensions
    {
          [DebuggerStepThrough] //該特性是用在方法前面的,在想要跳過的方法前面加上 
        public static T FromJson<T>(this string jsonStr)
        {
            return string.IsNullOrEmpty(jsonStr) ? default(T) : JsonConvert.DeserializeObject<T>(jsonStr);
        }
        /// <summary>
        /// 指示指定的字元串是 null、空或者僅由空白字元組成。
        /// </summary>
        [DebuggerStepThrough] //該特性是用在方法前面的,在想要跳過的方法前面加上 
        public static bool IsNullOrWhiteSpace(this string value)
        {
            return string.IsNullOrWhiteSpace(value);
        }
        /// <summary>
        /// 將Json字元串轉為DataTable
        /// </summary>
        /// <param name="jsonStr">Json字元串</param>
        /// <returns></returns>
        public static DataTable ToDataTable(this string jsonStr)
        {
            return jsonStr == null ? null : JsonConvert.DeserializeObject<DataTable>(jsonStr);
        }
    }
}
View Code

    3.儘量不在在object上面寫太多的擴展方法,寫之前要多加思考,不然在項目使用中任何類型智能提示出現一推擴展方法,看起來比較雜亂,針對int的擴展方法應該寫在int類型上,針對datetime的擴展方法應該寫在datetime類型上不應該都寫在object類型上

    4.如果方法名在擴展類型中已經使用,就不要再用這個名稱了,因為寫了也無效;

      

 

     

 


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

-Advertisement-
Play Games
更多相關文章
  • 圖的概念、存儲及遍歷 圖是一種特殊的數據結構,由點和邊構成,它可以用來描述元素之間的網狀關係,這個網狀沒有順序,也沒有層次,就是簡單的把各個元素連接起來。圖在我們的生活中也十分常見,地圖就是最簡單的例子。 圖的基本概念: 頂點集合為V,邊集合為E的圖記作G=(V,E)。另外,G=(V,E)的頂點數和 ...
  • 第四章 文件操作 4.1 文件基本操作 4.2 打開模式 r / w / a 【只讀只寫字元串】 r+ / w+ / a+ 【可讀可寫字元串】 rb / wb / ab 【只讀只寫二進位】 r+b / w+b / a+b 【可讀可寫二進位】 4.3 操作 read() , 全部讀到記憶體 read(1 ...
  • 8.1 靜態屬性和靜態方法 8.1.1 靜態屬性-提出問題 有一群小孩在玩堆雪人,不時有新的小孩加入,請問如何知道現在共有多少人在玩?請使用面向對象的思想,編寫程式解決 8.1.2 基本介紹 -Scala中靜態的概念-伴生對象 Scala語言是完全面向對象(萬物皆對象)的語言,所以並沒有靜態的操作( ...
  • 每一個新項目,都離不開身份認證,許可權授權,系統配置,還有相應的前端操作界面等基礎而重覆的工作,如果每一個新項目都要從0開始做這些重覆性工作,是很無味而繁瑣的。因此,OSharp 框架製作了一個基於 dotnet cli 命令行工具的快速啟動模板 ...
  • C#數據類型可以分值類型和引用類型。值類型,先說說一個概念 c#棧和堆. 一,棧和堆. 堆:在c裡面叫堆,在c#裡面其實叫托管堆。為什麼叫托管堆,我們往下看。 棧:就是堆棧,因為和堆一起叫著彆扭,就簡稱棧了。後進先出 托管堆不同於堆,它是由CLR(公共語言運行庫(Common Language Ru ...
  • 上接:.NetCore WebApi——基於JWT的簡單身份認證與授權(Swagger) 版本控制的好處是顯而易見的,利用Swagger展示不同版本的API更能體現效果。 1.安裝Nuget包:Microsoft.AspNetCore.Mvc.Versioning 2. 配置Startup類 2.1 ...
  • 1 //Program.cs 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Threading.Tasks; 6 using System.Windows.Forms; ... ...
  • 1 //Program.cs 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Threading.Tasks; 6 using System.Windows.Forms; ... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...