public enum Roles { // 堆代码 duidaima.com Author, Editor, Administrator, SalesRepresentative }然后,有一个方法接受这个枚举类型的参数:
public string DoSomething(Roles role) { return role.ToString(); }许多开发人员可能不会检查传入值是否为实际有效的枚举值。任何int类型都可以转换,可能出现下边这种代码:
var result = myObject.DoSomething((Roles)10);输出的结果是 “10”,如果后续代码中有基于这个枚举的分支语句或者条件判断,将产生错误的结果。对于这种情况,强类型字符串是一个不错的选择。
强类型字符串要声明成带有字符串构造函数的不可变值类型(struct),即要在该类型上用 readonly 修饰符,并为其实现 IEquatable<T> 接口。要覆写强类型字符串的 ToString() 方法,以返回隐式的字符串值。并将已知的强类型字符串通过静态只读属性声明到该类型上。为了让强类型字符串在通用代码的语言结构上看起来更像字符串或者枚举,需要为强类型字符串覆写相等运算符。
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)); } } }
这段代码更好地约束了加密哈希算法名称的输入,同时还扩展了其他功能。但比枚举繁琐不少。