Enum.ToString 可以支持像 "X2" 这样的精度说明符吗?
Can Enum.ToString support precision specifiers like "X2"?
Enum.ToString(string)
不支持直接使用 X2
或 D5
等精度说明符来对数值应用填充。 Formattings like ToString("X")
or ToString("D")
are implemented and well documented。当然,我可以明确地将它转换为 int
之前,因此利用为 ints 实现的格式说明符将其转换为填充字符串。
我想知道是否有一些直接支持枚举的这种功能而无需转换它们。乍一看,这似乎很奇怪,因为它不是直接实现的,因为它是为 int 或其他数字类型完成的。但也许我遗漏了一些更重要的东西,它可以明确地解释枚举不是那样做的?
public enum Number
{
Ten = 10
}
Console.WriteLine(Number.Ten); //OK: Ten
Console.WriteLine(Number.Ten.ToString()); //OK: Ten
Console.WriteLine(Number.Ten.ToString("D")); //OK: 10
Console.WriteLine(Number.Ten.ToString("D5")); //Expected 00010 - Failed: System.FormatException, can only be "G","g","X","x","F","f","D" or
Console.WriteLine(Number.Ten.ToString("X")); //OK: 0000000A
Console.WriteLine(Number.Ten.ToString("X2")); //Expected 0A - Failed: System.FormatException, can only be "G","g","X","x","F","f","D" or "d"
Console.WriteLine(10.ToString("X2")); //OK: 0A
Console.WriteLine(10.ToString("D5")); //OK: 00010
Console.WriteLine(((int)Number.Ten).ToString("X2"));//OK: 0A
来自 的简短摘要:
它不是明确存在的,因为它已经根据基础类型的大小隐式完成。因此,如果您喜欢 X2
而不是 X8
,只需使用字节作为基础类型,ToString("X")
的行为将类似于 ToString("X2")
。
Enum.ToString()
的实现表明它的设计使得只能使用某些格式说明符:
public String ToString(String format) {
if (format == null || format.Length == 0)
format = "G";
if (String.Compare(format, "G", StringComparison.OrdinalIgnoreCase) == 0)
return ToString();
if (String.Compare(format, "D", StringComparison.OrdinalIgnoreCase) == 0)
return GetValue().ToString();
if (String.Compare(format, "X", StringComparison.OrdinalIgnoreCase) == 0)
return InternalFormattedHexString(GetValue());
if (String.Compare(format, "F", StringComparison.OrdinalIgnoreCase) == 0)
return InternalFlagsFormat((RuntimeType)GetType(), GetValue());
throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
}
我认为它涵盖了最常见的场景:能够显示其数字、十六进制或字符串表示形式。显式转换的解决方法似乎足够便宜,不需要将其烘焙到框架中。
如果您想在不知道特定类型是什么的情况下使用基础类型的 ToString()
(无需转换!),您可以这样做:
var formattedValue = string.Format("{0:X2}",
Convert.ChangeType(Number.Ten, Number.Ten.GetTypeCode()));
这将输出“0A”。这可以很容易地包含在扩展方法中。
可能是因为枚举可以是字节、sbyte、short、ushort、int、uint、long 或 ulong。
如果您查看 .net 源代码,您将看到 ToString("X"):
的实现
switch (Convert.GetTypeCode(value))
{
case TypeCode.Boolean:
return Convert.ToByte((bool) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Char:
return ((ushort) (char) value).ToString("X4", (IFormatProvider) null);
case TypeCode.SByte:
return ((byte) (sbyte) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Byte:
return ((byte) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Int16:
return ((ushort) (short) value).ToString("X4", (IFormatProvider) null);
case TypeCode.UInt16:
return ((ushort) value).ToString("X4", (IFormatProvider) null);
case TypeCode.Int32:
return ((uint) (int) value).ToString("X8", (IFormatProvider) null);
case TypeCode.UInt32:
return ((uint) value).ToString("X8", (IFormatProvider) null);
case TypeCode.Int64:
return ((ulong) (long) value).ToString("X16", (IFormatProvider) null);
case TypeCode.UInt64:
return ((ulong) value).ToString("X16", (IFormatProvider) null);
default:
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
如果您将代码更改为此,它将使用 ToString("X2"):
public enum Number : byte
{
Ten = 10
}
Enum.ToString(string)
不支持直接使用 X2
或 D5
等精度说明符来对数值应用填充。 Formattings like ToString("X")
or ToString("D")
are implemented and well documented。当然,我可以明确地将它转换为 int
之前,因此利用为 ints 实现的格式说明符将其转换为填充字符串。
我想知道是否有一些直接支持枚举的这种功能而无需转换它们。乍一看,这似乎很奇怪,因为它不是直接实现的,因为它是为 int 或其他数字类型完成的。但也许我遗漏了一些更重要的东西,它可以明确地解释枚举不是那样做的?
public enum Number
{
Ten = 10
}
Console.WriteLine(Number.Ten); //OK: Ten
Console.WriteLine(Number.Ten.ToString()); //OK: Ten
Console.WriteLine(Number.Ten.ToString("D")); //OK: 10
Console.WriteLine(Number.Ten.ToString("D5")); //Expected 00010 - Failed: System.FormatException, can only be "G","g","X","x","F","f","D" or
Console.WriteLine(Number.Ten.ToString("X")); //OK: 0000000A
Console.WriteLine(Number.Ten.ToString("X2")); //Expected 0A - Failed: System.FormatException, can only be "G","g","X","x","F","f","D" or "d"
Console.WriteLine(10.ToString("X2")); //OK: 0A
Console.WriteLine(10.ToString("D5")); //OK: 00010
Console.WriteLine(((int)Number.Ten).ToString("X2"));//OK: 0A
来自 X2
而不是 X8
,只需使用字节作为基础类型,ToString("X")
的行为将类似于 ToString("X2")
。
Enum.ToString()
的实现表明它的设计使得只能使用某些格式说明符:
public String ToString(String format) {
if (format == null || format.Length == 0)
format = "G";
if (String.Compare(format, "G", StringComparison.OrdinalIgnoreCase) == 0)
return ToString();
if (String.Compare(format, "D", StringComparison.OrdinalIgnoreCase) == 0)
return GetValue().ToString();
if (String.Compare(format, "X", StringComparison.OrdinalIgnoreCase) == 0)
return InternalFormattedHexString(GetValue());
if (String.Compare(format, "F", StringComparison.OrdinalIgnoreCase) == 0)
return InternalFlagsFormat((RuntimeType)GetType(), GetValue());
throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
}
我认为它涵盖了最常见的场景:能够显示其数字、十六进制或字符串表示形式。显式转换的解决方法似乎足够便宜,不需要将其烘焙到框架中。
如果您想在不知道特定类型是什么的情况下使用基础类型的 ToString()
(无需转换!),您可以这样做:
var formattedValue = string.Format("{0:X2}",
Convert.ChangeType(Number.Ten, Number.Ten.GetTypeCode()));
这将输出“0A”。这可以很容易地包含在扩展方法中。
可能是因为枚举可以是字节、sbyte、short、ushort、int、uint、long 或 ulong。
如果您查看 .net 源代码,您将看到 ToString("X"):
的实现switch (Convert.GetTypeCode(value))
{
case TypeCode.Boolean:
return Convert.ToByte((bool) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Char:
return ((ushort) (char) value).ToString("X4", (IFormatProvider) null);
case TypeCode.SByte:
return ((byte) (sbyte) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Byte:
return ((byte) value).ToString("X2", (IFormatProvider) null);
case TypeCode.Int16:
return ((ushort) (short) value).ToString("X4", (IFormatProvider) null);
case TypeCode.UInt16:
return ((ushort) value).ToString("X4", (IFormatProvider) null);
case TypeCode.Int32:
return ((uint) (int) value).ToString("X8", (IFormatProvider) null);
case TypeCode.UInt32:
return ((uint) value).ToString("X8", (IFormatProvider) null);
case TypeCode.Int64:
return ((ulong) (long) value).ToString("X16", (IFormatProvider) null);
case TypeCode.UInt64:
return ((ulong) value).ToString("X16", (IFormatProvider) null);
default:
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
如果您将代码更改为此,它将使用 ToString("X2"):
public enum Number : byte
{
Ten = 10
}