I am an iOS developer and I regret that in Objective-C there is no the amazing method toString for enum like in C#
So I am very curious to know how the toString method works for enum in C#.
Maybe with your answers I will understand why Objective-C has not this method implemented.
Thanks
The C# compiler actually turns enumerations into regular class
types, and makes them behave like an enumeration by a combination of syntax sugar and some help from methods in the .NET framework (particularly the Type
and Enum
classes).
What actually happens when you declare an enum
type is that the compiler creates a hidden, specially-named class which conceptually looks like this:
public sealed class EnumName : Enum
{
public static readonly int FirstValue = 0;
public static readonly int SecondValue = 1;
// etc.
}
The Enum
base class is a special base class that you cannot use directly. It provides the ToString()
method. This sets off a series of function calls internal to the .NET framework. The code ends up in Type.GetEnumName()
and finally a private Type.GetEnumData()
method which uses reflection to examine the EnumName
class, look at its fields (enumeration values) and get and return their names.
The call graph (in chronological order) looks like this:
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()
calls Type.GetFields()
and iterates over them, copying the name and integral value (enum value) of each field into the output array.
Internally ToString
will call a method called Enum.InternalFormat
, which in turn just calls Enum.GetName
, here's the decompiled code (.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);
}
For enums marked with the Flags
attribute, it calls another method called InternalFlagsFormat
which builds up a CSV of all the enum names
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";
}
For the latest implementation, see the Microsoft source reference .
ToString simply returns the string equivelent of the Name of the specific enum value (note, this can differ from it's value).
public enum SomeEnum {
Text1 = 1,
Text2 = 2,
Text3 = 3,
}
var some = SomeEnum.Text1
some.ToString()
returns "Text1"
In the case of a flagged enum (using FlagsAttribute on the declaration) it would return a string equivelent of all selected enum values
var some = SomeEnum.Text1 & SomeEnum.Text2
"Text1 | Text2"
If we have an instance of an enumerated type we can map that value to one of several string representations by calling the ToString method inherited from System.Enum
Below is the sample code
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)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.