第三單元 擴展知識

来源:https://www.cnblogs.com/xuyubing/archive/2023/06/02/17452369.html
-Advertisement-
Play Games

1. 擴展方法 擴展方法使你能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種靜態方法,但可以像擴展類型上的實例方法一樣進行調用。 對於用 C#、F# 和 Visual Basic 編寫的客戶端代碼,調用擴展方法與調用在類型中定義的方法沒有明顯區別 ...


1. 擴展方法

 

擴展方法使你能夠向現有類型“添加”方法,而無需創建新的派生類型、重新編譯或以其他方式修改原始類型。 擴展方法是一種靜態方法,但可以像擴展類型上的實例方法一樣進行調用。 對於用 C#、F# 和 Visual Basic 編寫的客戶端代碼,調用擴展方法與調用在類型中定義的方法沒有明顯區別。

最常見的擴展方法是 LINQ 標準查詢運算符,它將查詢功能添加到現有的 System.Collections.IEnumerableSystem.Collections.Generic.IEnumerable 類型。 若要使用標準查詢運算符,請先使用 using System.Linq 指令將它們置於範圍中。 然後,任何實現了 IEnumerable 的類型看起來都具有 GroupByOrderByAverage 等實例方法。 在 IEnumerable 類型的實例(如 ListArray)後鍵入“dot”時,可以在 IntelliSense 語句完成中看到這些附加方法。

 

OrderBy 示例

下麵的示例演示如何對一個整數數組調用標準查詢運算符 OrderBy 方法。 括弧裡面的表達式是一個 lambda 表達式。 很多標準查詢運算符採用 Lambda 表達式作為參數,但這不是擴展方法的必要條件。 有關詳細信息,請參閱 Lambda 表達式

class ExtensionMethods2
{
​
    static void Main()
    {
        int[] ints = { 10, 45, 15, 39, 21, 26 };
        var result = ints.OrderBy(g => g);
        foreach (var i in result)
        {
            System.Console.Write(i + " ");
        }
    }
}
//Output: 10 15 21 26 39 45

 

擴展方法被定義為靜態方法,但它們是通過實例方法語法進行調用的。 它們的第一個參數指定方法操作的類型。 參數前面是修飾符。 僅當你使用 using 指令將命名空間顯式導入到源代碼中之後,擴展方法才位於範圍中。

 

自定義擴展方法

  1. 創建一個靜態類

  2. 創建一個靜態方法,這個方法即是你的擴展方法

  3. 方法中必須將你要擴展的類型通過參數傳遞進來

  4. 在你需要擴展的參數類型前面加this

namespace Utils; // 你的命名空間

// 擴展方法的工具類,註意一定要寫成static 靜態類
public static class ExtendUtils
{
    /**
     * 1. 靜態類下所有的方法都只能是static 方法
     * 2. 把你需要擴展的類型前面加this 
     */
    public static int ParseInt(this string str) 
    {
        if (string.IsNullOrWhiteSpace(str))
        {
            return 0;
        }

        int result = 0;

        if (!int.TryParse(str, out result))
        {
            return 0;
        }
        
        return result;

    }

 

 

使用

  1. 在你使用擴展方法之前,必須將擴展方法所在命名空間引用進來

using System;
using NUnit.Framework;
using Utils; // 若要使用擴展方法,必須先將其所在命名空間引用進來

namespace TestProject1;

public class Tests
{
    [SetUp]
    public void Setup()
    {
    }

    [Test]
    public void Test1()
    {
        string strNumber = "30";
        Console.WriteLine(strNumber.ParseInt()); // 使用擴展方法
    }
 
}

 

2. 特性

使用特性,可以有效地將元數據或聲明性信息與代碼(程式集、類型、方法、屬性等)相關聯。 將特性與程式實體相關聯後,可以在運行時使用反射這項技術查詢特性,常運用於AOP技術。

特性具有以下屬性:

  • 特性向程式添加元數據。 元數據是程式中定義的類型的相關信息。 所有 .NET 程式集都包含一組指定的元數據,用於描述程式集中定義的類型和類型成員。 可以添加自定義特性來指定所需的其他任何信息。 有關詳細信息,請參閱創建自定義特性 (C#)

  • 可以將一個或多個特性應用於整個程式集、模塊或較小的程式元素(如類和屬性)。

  • 特性可以像方法和屬性一樣接受自變數。

  • 程式可使用反射來檢查自己的元數據或其他程式中的元數據。 有關詳細信息,請參閱使用反射訪問特性 (C#)

 

創建自定義特性

可通過定義特性類創建自己的自定義特性,特性類是直接或間接派生自 Attribute 的類,可快速輕鬆地識別元數據中的特性定義。 假設希望使用編寫類型的程式員的姓名來標記該類型。 可能需要定義一個自定義 Author 特性類:

[System.AttributeUsage(System.AttributeTargets.Class |  
                       System.AttributeTargets.Struct)  
]  
public class AuthorAttribute : System.Attribute  
{  
    private string name;  
    public double version;  
  
    public AuthorAttribute(string name)  
    {  
        this.name = name;  
        version = 1.0;  
    }  
}  

 

類名 AuthorAttribute 是該特性的名稱,即 Author 加上 Attribute 尾碼。 由於該類派生自 System.Attribute,因此它是一個自定義特性類。 構造函數的參數是自定義特性的位置參數。 在此示例中,name 是位置參數。 所有公共讀寫欄位或屬性都是命名參數。 在本例中,version 是唯一的命名參數。 請註意,使用 AttributeUsage 特性可使 Author 特性僅對類和 struct 聲明有效。

可按如下方式使用這一新特性:

[Author("P. Ackerman", version = 1.1)]  
class SampleClass  
{  
    // P. Ackerman's code goes here...  
}  
AttributeUsage 有一個命名參數 AllowMultiple,通過此命名參數可一次或多次使用自定義特性。 下麵的代碼示例創建了一個多用特性。

[System.AttributeUsage(System.AttributeTargets.Class |  
                       System.AttributeTargets.Struct,  
                       AllowMultiple = true)  // multiuse attribute  
]  
public class AuthorAttribute : System.Attribute  

 

在下麵的代碼示例中,某個類應用了同一類型的多個特性。

[Author("P. Ackerman", version = 1.1)]  
[Author("R. Koch", version = 1.2)]  
class SampleClass  
{  
    // P. Ackerman's code goes here...  
    // R. Koch's code goes here...  
}  

3. JSON 操作

JSON: JavaScript Object Notation(JavaScript 對象表示法)

JSON 是存儲和交換文本信息的語法,類似 XML。

JSON 比 XML 更小、更快,更易解析。

1. 什麼是Json

  • SON 指的是 JavaScript 對象表示法(JavaScript Object Notation)

  • JSON 是輕量級的文本數據交換格式

  • JSON 獨立於語言:JSON 使用 Javascript語法來描述數據對象,但是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不同的編程語言。 目前非常多的動態(PHP,JSP,.NET)編程語言都支持JSON。

  • JSON 具有自我描述性,更易理解

{
    "sites": [
    {id:1, "name":"C#教程" , "url":"www.runoob.com" }, 
    {id:2, "name":"google" , "url":"www.google.com" }, 
    {id:3, "name":"微博" , "url":"www.weibo.com" }
    ]
}

 

大家平時在自己寫JSON時,可以藉助於 線上JSON校驗格式化工具(Be JSON)

{
    "sites": [
        {
            "name": "菜鳥教程",
            "url": "www.runoob.com"
        },
        {
            "name": "google",
            "url": "www.google.com"
        },
        {
            "name": "微博",
            "url": "www.weibo.com"
        }
    ]
}

JSON 語法規則

  • 數據在鍵值對中

  • 數據由逗號分隔

  • 花括弧保存對象

  • 方括弧保存數組

     

JSON 名稱/值對

JSON 數據的書寫格式是:名稱/值對。

名稱/值對組合中的名稱寫在前面(在雙引號中),值對寫在後面(同樣在雙引號中),中間

用冒號隔開:"firstName":"John"

 

JSON 值可以是:

數字(整數或浮點數)

字元串(在雙引號中)

邏輯值(

true 或 false)

數組(在方括弧中)

對象(在花括弧中)

null

JSON數據結構

json簡單說就是javascript中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通

過這兩種結構可以表示各種複雜的結構

1、對象:對象在js中表示為“{}”括起來的內容,數據結構為 {key:value,key:

value,...}的鍵值對的結構,在面向對象的語言中,key為對象的屬性,value為對應的屬性

值,所以很容易理解,取值方法為 對象.key (

c# 對象[key])獲取屬性值,這個屬性值的

類型可以是 數字、字元串、數組、對象幾種。

2、數組:數組在js中是中括弧“[]”括起來的內容,數據結構為

["java","javascript","vb",...],取值方式和所有語言中一樣,使用索引獲取,欄位值的

類型可以是 數字、字元串、數組、對象幾種。

經過對象、數組2種結構就可以組合成複雜的數據結構了。

.Net 中提供的JSON解析組件

  • Newtonsoft.Json

  • fastjson

 

2. 序列化與反序列化

使用nuget 工具 將 Newtonsoft.Json 引用到當前項目中

序列化

對象轉換為Json

using Newtonsoft.Json;

public class Site
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
}

// 對象轉換為Json
[Test]
public void ObjectToJson()
{
    Site site = new()
    {
        Id = 1,
        Name = "任我行網路教育有限公司",
        Url = "www.renwoxing.com"
    };

    string json = JsonConvert.SerializeObject(site);
    Console.WriteLine(json);
}
// 輸出結果
{"Id":1,"Name":"任我行網路教育有限公司","Url":"www.renwoxing.com"}

 

集合序列化

[Test]
public void ListToJson()
{
    List<Site> sites = new List<Site>();
    sites.Add(new()
              {
                  Id = 1,
                  Name = "任我行網路教育有限公司",
                  Url = "www.renwoxing.com"
              });

    sites.Add(new()
              {
                  Id = 2,
                  Name = "百度",
                  Url = "www.baidu.com"
              });

    string json = JsonConvert.SerializeObject(sites);
    Console.WriteLine(json);
}

 

輸出結果:

[{
    "Id": 1,
    "Name": "任我行網路教育有限公司",
    "Url": "www.renwoxing.com"
}, {
    "Id": 2,
    "Name": "百度",
    "Url": "www.baidu.com"
}]

反序列化

json轉對象

[Test]
public void JsonToObject()
{
    string json = "{\"Id\":1,\"Name\":\"任我行網路教育有限公司\",\"Url\":\"www.renwoxing.com\"}";
    Site site = JsonConvert.DeserializeObject<Site>(json);
}

 

json轉集合

[Test]
public void JsonToList()
{
    string json = "[{\"Id\": 1,\"Name\": \"任我行網路教育有限公司\",\"Url\": \"www.renwoxing.com\"}, 
            {\"Id\": 2,\"Name\": \"百度\",\"Url\": \"www.baidu.com\"}]
"; List<Site> sites = JsonConvert.DeserializeObject<List<Site>>(json); Console.WriteLine(sites.Count); }

 

4. 綜合訓練

結合反射,枚舉,特性,擴展方法,完成綜合練習。

  1. 聲明枚舉如下:

    using System.ComponentModel;
    /**
     * 訂單狀態
     */
    public enum OrderStateEnum
    {
        [Description("待支付")]
        WaitPay,
        [Description("待發貨")]
        WaitSend,
        [Description("待收貨")]
        WaitReceive,
        [Description("待評論")]
        WaitComment,
        [Description("已完成")]
        Finish,
        [Description("取消訂單")]
        Cancel
    }

     

  2. 要求 封裝OrderStateEnum的擴展 方法 GetDescription() ,效果如下

    string desc = OrderStateEnum.WaitPay.GetDescription();
    Console.WriteLine(desc); // 輸出:待支付

     

 

   3. 具體實現

/// <summary>
/// 獲取描述特性信息
/// </summary>
/// <param name="stateEnum"></param>
/// <returns></returns>
public static string GetDescription(this OrderStateEnum stateEnum)
{
    var type = stateEnum.GetType();
    var fieldInfo = type.GetField(stateEnum.ToString());
    var desc = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
    return desc.Description;
}

 

 

配套視頻鏈接:

C# 高級編程,.Net6 系列 開發第三階段,學完拿捏你的面試官,.net6 進階學習(已完結)_嗶哩嗶哩_bilibili

 

 

 

海闊平魚躍,天高任我行,給我一片藍天,讓我自由翱翔。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 1.數值列表 列表非常適合用於存儲數字集合,而python提供了很多工具,可幫助我們高速地處理數字列表。 ## 1.1 range函數 python的range函數能夠輕鬆的生成連續一系列數字。 其語法格式:range(第一個數值,第二個數值) 編寫程式如下所示 ![image](https:/ ...
  • 時間序列數據是數據分析中一類常見且重要的數據。 它們按照時間順序記錄,通常是從某些現象的觀察中收集的,比如經濟指標、氣象數據、股票價格、銷售數據等等。 時間序列數據的特點是有規律地隨著時間變化而變化,它們的變化趨勢可以被分析和預測。時間序列分析是一種用於預測未來值或評估過去值的統計方法,常常被用於預 ...
  • 基於java的線上商城設計與實現,線上購物平臺,校園購物商城,商品銷售平臺,基於Java的電商平臺;電商平臺,買家和賣家可以在此平臺上進行銷售和交易,節約了大量的線下時間成本,購物車的功能,校園交易平臺等等; ...
  • 昨天遇到參數key大小寫不一致導致校驗簽名失敗的問題,查了很長時間才找到原因。看了一下FastJson源碼,發現JSON.toObject中轉換成對象的時候會忽略大小寫。 所以,當使用了JSON.toObject將json轉成Java對象後,再用JSON.toObject轉成json,key值就變了 ...
  • # 前言 在上一篇文章中,給大家講解了泛型的概念、作用、使用場景,以及泛型集合、泛型介面和泛型類的用法,但受限於篇幅,並沒有把泛型的內容講解完畢。所以今天我們會繼續學習泛型方法、泛型擦除,以及通配符等的內容,希望大家繼續做好學習的準備哦。 *** 全文大約【**4600】** 字,不說廢話,只講可以 ...
  • [toc] 這篇文章是我之前總結的一篇文章,因為整理博客的原因,原有博客已經註銷,但這篇文章對一些讀者很有用,所以現在新瓶裝舊酒重新整理回來分享給大家。 最近一段時間生產環境頻繁出問題,每次都會生成一個hs_err_pid*.log文件,因為工作內容的原因,在此之前並沒有瞭解過相關內容,趁此機會學習 ...
  • 隨著技術的發展,ASP.NET Core MVC也推出了好長時間,經過不斷的版本更新迭代,已經越來越完善,本系列文章主要講解ASP.NET Core MVC開發B/S系統過程中所涉及到的相關內容,適用於初學者,在校畢業生,或其他想從事ASP.NET Core MVC 系統開發的人員。 經過前幾篇文章... ...
  • 以前在隨筆《Winform開發框架之客戶關係管理系統(CRM)的開發總結系列1-界面功能展示 》的幾篇隨筆中介紹過基於WInform開發框架開發的CRM系統,系統的功能主要也是圍繞著客戶相關信息來進行管理的。本篇隨筆介紹在最新的《SqlSugar開發框架》中整合CRM系統模塊的功能。 ...
一周排行
    -Advertisement-
    Play Games
  • 通過WPF的按鈕、文本輸入框實現了一個簡單的SpinBox數字輸入用戶組件並可以通過數據綁定數值和步長。本文中介紹了通過Xaml代碼實現自定義組件的佈局,依賴屬性的定義和使用等知識點。 ...
  • 以前,我看到一個朋友在對一個系統做初始化的時候,通過一組魔幻般的按鍵,調出來一個隱藏的系統設置界面,這個界面在常規的菜單或者工具欄是看不到的,因為它是一個後臺設置的關鍵界面,不公開,同時避免常規用戶的誤操作,它是作為一個超級管理員的入口功能,這個是很不錯的思路。其實Winform做這樣的處理也是很容... ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他的程式每次關閉時就會自動崩潰,一直找不到原因讓我幫忙看一下怎麼回事,這位朋友應該是第二次找我了,分析了下 dump 還是挺經典的,拿出來給大家分享一下吧。 二:WinDbg 分析 1. 為什麼會崩潰 找崩潰原因比較簡單,用 !analyze -v 命 ...
  • 在一些報表模塊中,需要我們根據用戶操作的名稱,來動態根據人員姓名,更新報表的簽名圖片,也就是電子手寫簽名效果,本篇隨筆介紹一下使用FastReport報表動態更新人員簽名圖片。 ...
  • 最新內容優先發佈於個人博客:小虎技術分享站,隨後逐步搬運到博客園。 創作不易,如果覺得有用請在Github上為博主點亮一顆小星星吧! 博主開始學習編程於11年前,年少時還只會使用cin 和cout ,給單片機點點燈。那時候,類似async/await 和future/promise 模型的認知還不是 ...
  • 之前在阿裡雲ECS 99元/年的活動實例上搭建了一個測試用的MINIO服務,以前都是直接當基礎設施來使用的,這次準備自己學一下S3相容API相關的對象存儲開發,因此有了這個小工具。目前僅包含上傳功能,後續計劃開發一個類似圖床的對象存儲應用。 ...
  • 目錄簡介快速入門安裝 NuGet 包實體類User資料庫類DbFactory增刪改查InsertSelectUpdateDelete總結 簡介 NPoco 是 PetaPoco 的一個分支,具有一些額外的功能,截至現在 github 星數 839。NPoco 中文資料沒多少,我是被博客園群友推薦的, ...
  • 前言 前面使用 Admin.Core 的代碼生成器生成了通用代碼生成器的基礎模塊 分組,模板,項目,項目模型,項目欄位的基礎功能,本篇繼續完善,實現最核心的模板生成功能,並提供生成預覽及代碼文件壓縮下載 準備 首先清楚幾個模塊的關係,如何使用,簡單畫一個流程圖 前面完成了基礎的模板組,模板管理,項目 ...
  • 假設需要實現一個圖標和文本結合的按鈕 ,普通做法是 直接重寫該按鈕的模板; 如果想作為通用的呢? 兩種做法: 附加屬性 自定義控制項 推薦使用附加屬性的形式 第一種:附加屬性 創建Button的附加屬性 ButtonExtensions 1 public static class ButtonExte ...
  • 在C#中,委托是一種引用類型的數據類型,允許我們封裝方法的引用。通過使用委托,我們可以將方法作為參數傳遞給其他方法,或者將多個方法組合在一起,從而實現更靈活的編程模式。委托類似於函數指針,但提供了類型安全和垃圾回收等現代語言特性。 基本概念 定義委托 定義委托需要指定它所代表的方法的原型,包括返回類 ...