All types in the CLR inherit from System.Object in which the virtual method of the string representation of the current object is defined - ToString . Any type can override this method, thereby changing the default view, which is defined in System.Object - output the full name of the type.
For example, the type Int32 (int) overrides this method to represent the stored value as formatted, depending on the regional settings and format.
Every time you define an enumeration, you create a subclass of the System.Enum class in which, as you already guessed, the ToString method is also predefined to represent the current enumeration value as a string. For your listing (Vehicles), this IL will be generated.
.class private auto ansi sealed Vehicles extends [mscorlib]System.Enum { .field public specialname rtspecialname int32 value__ .field public static literal valuetype Vehicles car = int32(0x00000000) .field public static literal valuetype Vehicles plane = int32(0x00000001) ... .field public static literal valuetype Vehicles truck = int32(0x00000001) } // end of class Vehicles
What corresponds approximately to such a code ( I am a translator from IL, so it’s best to double-check :)
sealed class Vehicles : System.Enum { public const Vehicles car = 0; public const Vehicles plane = 1; ... public const Vehicles truck = 1; }
Now how the method ToString which is used by the Console.WriteLine method finds a field name. In .NET there is a special mechanism called reflection, with which you can get information about arbitrary types (for example, the names of fields and their values) with the help of this mechanism. Enum scans the list of fields, and if there are matches by value, then it returns this name. In practice, this code is responsible for this, which is called from the Enum.ToString method Enum.ToString
private static String InternalFormat(RuntimeType eT, Object value) { if (!eT.IsDefined(typeof(System.FlagsAttribute), false)) { String retval = GetName(eT, value); if (retval == null) return value.ToString(); else return retval; ... }
It clearly shows that if the enumeration does not have the Flags attribute, then the method should simply return the field name or, in case of a mismatch, return the value.
Then why in the first conclusion of the truck, and not the plane
As I said above, the names of all fields and values are selected by means of reflection. The code then sorts the field values and uses a binary search to find a match. Thus, the search will simply return the first match. This code from System.Enum is responsible for this System.Enum
Array values = GetEnumRawConstantValues(); int index = BinarySearch(values, value); if (index >= 0) { string[] names = GetEnumNames(); return names[index]; }
You can try to manipulate this search by placing the same values on the boundary of the segments:
enum Vehicles { car = 0, plane = 1, cat = 2, ship = 2, helicopter = 3, truck = 4 } ... string name = ((Vehicles) 2).ToString(); Console.WriteLine(name); // cat
But still it is better to assign different values to the enumeration fields :)
enummethod and theintmethod defineToString()differently - Andrey NOP