第三單元 擴展知識

来源: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
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...