我是一名iOS开发人员,我很遗憾在Objective-C中没有像C#中那样令人惊奇的方法来实现枚举#
所以我很想知道toString方法如何适用于C#中的枚举。
也许有了你的答案,我将理解为什么Objective-C没有实现这个方法。
由于
答案 0 :(得分:8)
C#编译器实际上将枚举转换为常规class
类型,并使它们的行为类似于syntax sugar的组合以及.NET框架中某些方法的帮助(特别是{{3 }和Type
类)。
当您声明enum
类型时,实际发生的是编译器创建一个隐藏的,特别命名的类,其概念如下所示:
public sealed class EnumName : Enum
{
public static readonly int FirstValue = 0;
public static readonly int SecondValue = 1;
// etc.
}
Enum
基类是一个不能直接使用的特殊基类。它提供ToString()
方法。这引发了.NET框架内部的一系列函数调用。代码最终在Enum
中,最后是一个私有Type.GetEnumData()
方法,它使用反射来检查EnumName
类,查看其字段(枚举值)并获取并返回其名称。
调用图(按时间顺序)如下所示:
Enum.ToString()
Enum.InternalFormat(RuntimeType, object)
Enum.GetName(RuntimeType, object)
Type.GetEnumName(object)
Type.GetEnumRawConstantValues()
Type.GetEnumData(out string[], out Array)
Type.GetEnumNames()
Type.GetEnumData(out string[], out Array)
GetEnumData()
调用Type.GetEnumName()
并迭代它们,将每个字段的名称和整数值(枚举值)复制到输出数组中。
答案 1 :(得分:2)
内部ToString
将调用一个名为Enum.InternalFormat
的方法,该方法只调用Enum.GetName
,这里是反编译代码(.NET v4.0)
[__DynamicallyInvokable]
public override string ToString()
{
return Enum.InternalFormat((RuntimeType) this.GetType(), this.GetValue());
}
private static string InternalFormat(RuntimeType eT, object value)
{
if (!eT.IsDefined(typeof (FlagsAttribute), false))
return Enum.GetName((Type) eT, value) ?? value.ToString();
else
return Enum.InternalFlagsFormat(eT, value);
}
对于标有Flags
属性的枚举,它会调用另一个名为InternalFlagsFormat
的方法,该方法会构建所有枚举名称的CSV
private static string InternalFlagsFormat(RuntimeType eT, object value)
{
ulong num1 = Enum.ToUInt64(value);
ulong[] values;
string[] names;
Enum.GetCachedValuesAndNames(eT, out values, out names, true, true);
int index = values.Length - 1;
StringBuilder stringBuilder = new StringBuilder();
bool flag = true;
ulong num2 = num1;
for (; index >= 0 && (index != 0 || (long) values[index] != 0L); --index)
{
if (((long) num1 & (long) values[index]) == (long) values[index])
{
num1 -= values[index];
if (!flag)
stringBuilder.Insert(0, ", ");
stringBuilder.Insert(0, names[index]);
flag = false;
}
}
if ((long) num1 != 0L)
return value.ToString();
if ((long) num2 != 0L)
return ((object) stringBuilder).ToString();
if (values.Length > 0 && (long) values[0] == 0L)
return names[0];
else
return "0";
}
有关最新实施,请参阅Microsoft source reference。
答案 2 :(得分:0)
ToString只返回特定枚举值的名称等效字符串(注意,这可能与它的值不同)。
public enum SomeEnum {
Text1 = 1,
Text2 = 2,
Text3 = 3,
}
var some = SomeEnum.Text1
some.ToString()
返回"Text1"
如果是标记的枚举(在声明中使用FlagsAttribute),它将返回一个等于所有选定枚举值的字符串
var some = SomeEnum.Text1 & SomeEnum.Text2
"Text1 | Text2"
答案 3 :(得分:0)
如果我们有一个枚举类型的实例,我们可以通过调用从System.Enum继承的ToString方法将该值映射到几个字符串表示之一
以下是示例代码
class Program
{
enum Days
{
Sun,
Mon,
Tue,
Wed,
Thu,
Fri,
Sat
};
static void Main(string[] args)
{
Days obj = Days.Mon;
Console.WriteLine(obj.ToString("G")); // output - Mon (Normal)
Console.WriteLine(obj.ToString("D")); // output - 1 (Decimal)
Console.WriteLine(obj.ToString("X")); // output - 00000001 (Hexadecimal)
}
}