91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何更改C#中Record構造函數的行為

發布時間:2021-08-30 09:19:25 來源:億速云 閱讀:106 作者:小新 欄目:開發技術

這篇文章主要介紹如何更改C#中Record構造函數的行為,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

Record是 C# 9 中的一個新功能。Record是從Structs借用的特殊類, 因為它們具有 基于值的相等性,您可以將它們視為兩類類型之間的混合體。默認情況下,它們或多或少是不可變的,并且具有語法糖,使聲明更容易和更簡潔。但是,語法糖可能會掩蓋更多標準任務,例如更改默認構造函數的行為。在某些情況下,您可能需要這樣做以進行驗證。本文將向您展示如何實現這一目標。

以這個簡單的示例類為例:

public class StringValidator
{
    public string InputString { get; }


    public StringValidator(string inputString)
    {
        if (string.IsNullOrEmpty(inputString)) throw new ArgumentNullException(nameof(inputString));


        InputString = inputString;
    }
}

很明顯,如果消費者試圖在沒有有效字符串的情況下創建此類的實例,他們將收到異常。創建Record的標準語法如下所示:

public record StringValidator(string InputString);

它既友好又簡潔,但并不清楚您將如何驗證字符串。此定義告訴編譯器將有一個名為 的屬性InputString,并且構造函數會將值從參數傳遞給該屬性。我們需要刪除語法糖來驗證字符串。幸運的是,這很容易。我們不需要使用新語法來定義我們的Record。我們可以定義類似于類的Record,但將關鍵字類更改為Record。

public record StringValidator
{
    public string InputString { get;  }


    public StringValidator(string inputString)
    {
        if (string.IsNullOrEmpty(inputString)) throw new ArgumentNullException(nameof(inputString));


        InputString = inputString;
    }
}

不幸的是,這意味著我們不能使用 非破壞性突變[3]。該with關鍵字給我們創造了一些屬性來更改Record的新版本的功能。這意味著我們不會修改Record的原始實例,但我們會得到它的副本。這是 Fluent API 和函數式編程的常用方法。這使我們能夠保持不變性。

為了允許非破壞性突變,我們需要添加init屬性訪問器。這與構造函數的工作方式類似,但僅在對象初始化期間調用。這是實現init訪問器的更完整的解決方案。這允許您共享構造函數邏輯和初始化邏輯。

using System;


namespace ConsoleApp25
{
    class Program
    {
        static void Main(string[] args)
        {
            //This throws an exception from the constructor
            //var stringValidator = new StringValidator(null);


            var stringValidator1 = new StringValidator("First");
            var stringValidator2 = stringValidator1 with { InputString = "Second" };
            Console.WriteLine(stringValidator2.InputString);


            //This throws an exception from the init accessor
            //var stringValidator3 = stringValidator1 with { InputString = null };


            //Output: Second
        }
    }


    public record StringValidator
    {
        private string inputString;


        public string InputString
        {
            get => inputString;
            init
            {
                //This init accessor works like the set accessor
                ValidateInputString(value);
                inputString = value;
            }
        }


        public StringValidator(string inputString)
        {
            ValidateInputString(inputString);
            InputString = inputString;
        }


        public static void ValidateInputString(string inputString)
        {
            if (string.IsNullOrEmpty(inputString)) throw new ArgumentNullException(nameof(inputString));
        }
    }
}

Record構造函數應該有邏輯嗎?

這是一個有爭議的辯論,超出了本文的范圍。很多人會爭辯說你不應該把邏輯放在構造函數中。Record的設計鼓勵您不要在構造函數或 init 訪問器中放置邏輯。一般來說,Record應該及時代表數據的快照狀態。您不需要應用邏輯,因為假設您知道此時數據的狀態。但是,就像其他所有編程結構一樣,無法知道Record可能會產生哪些用例。這是庫 Urls 中的[4]一個示例[5][6]它將 URL 視為不可變Record:

using System.Net;


namespace Urls
{
    public record QueryParameter
    {
        private string? fieldValue;


        public string FieldName { get; init; }
        public string? Value
        {
            get => fieldValue; init
            {
                fieldValue = WebUtility.UrlDecode(value);
            }
        }


        public QueryParameter(string fieldName, string? value)
        {
            FieldName = fieldName;
            fieldValue = WebUtility.UrlDecode(value);
        }


        public override string ToString()
            => $"{FieldName}{(Value != null ? "=" : "")}{WebUtility.UrlEncode(Value)}";
    }
}

我們確保在存儲查詢值時對其進行解碼,然后在將其用作 Url 的一部分時對其進行編碼。

以上是“如何更改C#中Record構造函數的行為”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

山东省| 郧西县| 庐江县| 渭南市| 将乐县| 隆昌县| 浦城县| 大名县| 海淀区| 岚皋县| 清远市| 抚松县| 定安县| 巧家县| 大石桥市| 西宁市| 鹿邑县| 晋州市| 石台县| 龙里县| 兴安盟| 邵武市| 娄底市| 道孚县| 靖宇县| 遵化市| 赤城县| 广灵县| 华亭县| 札达县| 会东县| 忻城县| 卢湾区| 西青区| 曲靖市| 襄城县| 安吉县| 中西区| 东安县| 萨嘎县| 浦城县|