欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET的強類型字符串(Strongly typed string)詳解

 更新時間:2024年12月02日 09:33:10   作者:czwy  
強類型字符串是一種編譯時類型檢查的字符串表示方法,類似于枚舉,但具有更好的擴展性和約束性,強類型字符串可以提供更好的可讀性和維護(hù)性,并且可以避免運行時錯誤,本文介紹什么是.NET的強類型字符串(Strongly typed string),感興趣的朋友一起看看吧

.NET中,強類型字符串(Strongly typed string)并不是一個官方的概念,是指使用特定的結(jié)構(gòu)來表示某種類型字符串?dāng)?shù)據(jù)的編碼實踐。類似于枚舉,可以提供編譯時檢查類型,減少運行時錯誤,以及更好的可讀性和維護(hù)性。相比于枚舉,具有更好的擴展性以及更強的約束性。

枚舉

枚舉提供了一種便捷的方法來使用相關(guān)常數(shù)集并將常數(shù)值與名稱相關(guān)聯(lián),具有類型安全、可讀性高以及編譯時檢查等優(yōu)點。但是枚舉類型不能定義任何方法、屬性或事件,只能通過擴展方法功能模擬向枚舉類型添加方法。
盡管枚舉提供了編譯時檢查,但對輸入值的約束是有限的。例如,下面這個枚舉有四個值,默認(rèn)情況下是int類型。取值范圍為0 ~ 3。

public enum Roles {
    Author,
    Editor,
    Administrator,
    SalesRepresentative
}

然后,有一個方法接受這個枚舉類型的參數(shù):

public string DoSomething(Roles role) {
    return role.ToString();
}

許多開發(fā)人員可能不會檢查傳入值是否為實際有效的枚舉值。任何int類型都可以轉(zhuǎn)換,可能出現(xiàn)下邊這種代碼:

var result = myObject.DoSomething((Roles)10);

輸出的結(jié)果是 “10”,如果后續(xù)代碼中有基于這個枚舉的分支語句或者條件判斷,將產(chǎn)生錯誤的結(jié)果。對于這種情況,強類型字符串是一個不錯的選擇。

強類型字符串(Strongly typed string)

強類型字符串要聲明成帶有字符串構(gòu)造函數(shù)的不可變值類型(struct),即要在該類型上用 readonly 修飾符,并為其實現(xiàn) IEquatable<T> 接口。要覆寫強類型字符串的 ToString() 方法,以返回隱式的字符串值。并將已知的強類型字符串通過靜態(tài)只讀屬性聲明到該類型上。
為了讓強類型字符串在通用代碼的語言結(jié)構(gòu)上看起來更像字符串或者枚舉,需要為強類型字符串覆寫相等運算符。
以下就是 .NET 源碼中加密哈希算法的名稱強類型字符串HashAlgorithmName的代碼

using System.Diagnostics.CodeAnalysis;
namespace System.Security.Cryptography
{
    public readonly struct HashAlgorithmName : IEquatable<HashAlgorithmName>
    {
        public static HashAlgorithmName MD5 { get { return new HashAlgorithmName("MD5"); } }
        public static HashAlgorithmName SHA1 { get { return new HashAlgorithmName("SHA1"); } }
        public static HashAlgorithmName SHA256 { get { return new HashAlgorithmName("SHA256"); } }
        public static HashAlgorithmName SHA384 { get { return new HashAlgorithmName("SHA384"); } }
        public static HashAlgorithmName SHA512 { get { return new HashAlgorithmName("SHA512"); } }
        public static HashAlgorithmName SHA3_256 => new HashAlgorithmName("SHA3-256");
        public static HashAlgorithmName SHA3_384 => new HashAlgorithmName("SHA3-384");
        public static HashAlgorithmName SHA3_512 => new HashAlgorithmName("SHA3-512");
        private readonly string? _name;
        public HashAlgorithmName(string? name)
        {
            // Note: No validation because we have to deal with default(HashAlgorithmName) regardless.
            _name = name;
        }
        public string? Name
        {
            get { return _name; }
        }
        public override string ToString()
        {
            return _name ?? string.Empty;
        }
        public override bool Equals([NotNullWhen(true)] object? obj)
        {
            return obj is HashAlgorithmName && Equals((HashAlgorithmName)obj);
        }
        public bool Equals(HashAlgorithmName other)
        {
            // NOTE: intentionally ordinal and case sensitive, matches CNG.
            return _name == other._name;
        }
        public override int GetHashCode()
        {
            return _name == null ? 0 : _name.GetHashCode();
        }
        public static bool operator ==(HashAlgorithmName left, HashAlgorithmName right)
        {
            return left.Equals(right);
        }
        public static bool operator !=(HashAlgorithmName left, HashAlgorithmName right)
        {
            return !(left == right);
        }
        //其他擴展功能
        public static bool TryFromOid(string oidValue, out HashAlgorithmName value)
        {
            ArgumentNullException.ThrowIfNull(oidValue);
            switch (oidValue)
            {
                case Oids.Md5:
                    value = MD5;
                    return true;
                case Oids.Sha1:
                    value = SHA1;
                    return true;
                case Oids.Sha256:
                    value = SHA256;
                    return true;
                case Oids.Sha384:
                    value = SHA384;
                    return true;
                case Oids.Sha512:
                    value = SHA512;
                    return true;
                case Oids.Sha3_256:
                    value = SHA3_256;
                    return true;
                case Oids.Sha3_384:
                    value = SHA3_384;
                    return true;
                case Oids.Sha3_512:
                    value = SHA3_512;
                    return true;
                default:
                    value = default;
                    return false;
            }
        }
        public static HashAlgorithmName FromOid(string oidValue)
        {
            if (TryFromOid(oidValue, out HashAlgorithmName value))
            {
                return value;
            }
            throw new CryptographicException(SR.Format(SR.Cryptography_InvalidHashAlgorithmOid, oidValue));
        }
    }
}

這段代碼更好地約束了加密哈希算法名稱的輸入,同時還擴展了其他功能。但比枚舉繁瑣不少。
根據(jù)《框架設(shè)計指南》建議:當(dāng)基類支持一組固定的輸入?yún)?shù),但是派生類需要支持更多的參數(shù)時,建議使用強類型字符串;當(dāng)僅由密封類型使用時,只需要使用預(yù)定義的值,枚舉將是更好的選擇。
此外,枚舉通常定義的是封閉的選項集,對于操作系統(tǒng)版本這種開放集合,也建議使用強類型字符串??丶?nbsp;HandyControl 中的 SystemVersionInfo正是這樣的例子。

參考資料

Enum Alternatives in C# | Blog

使用枚舉類(而不是枚舉類型) - .NET | Microsoft Learn

到此這篇關(guān)于什么是.NET的強類型字符串(Strongly typed string)的文章就介紹到這了,更多相關(guān).NET強類型字符串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論