Fixed Type.GetEnumNames sort order (it's specified on MSDN). Previously this method...
authorJames Bellinger <jfb@zer7.com>
Sun, 8 Jul 2012 04:31:57 +0000 (00:31 -0400)
committerJames Bellinger <jfb@zer7.com>
Sun, 8 Jul 2012 04:31:57 +0000 (00:31 -0400)
Ran into this while calling Type.GetEnumNames and Type.GetEnumValues.
To my surprise the pairs didn't match up. Anyway, here's a fix.

mcs/class/corlib/System/Enum.cs
mcs/class/corlib/System/Type.cs
mcs/class/corlib/Test/System/TypeTest.cs

index 0ce1c67a702a57fd4892d418b4208900694add16..4cc6f3c55413ce9a421fbea0c27e5c62f4351a50 100644 (file)
@@ -167,7 +167,7 @@ namespace System
                        names = other.names;
                        name_hash = other.name_hash;
                }
-
+               
                internal static void GetInfo (Type enumType, out MonoEnumInfo info)
                {
                        /* First check the thread-local cache without locking */
@@ -187,18 +187,9 @@ namespace System
 
                        get_enum_info (enumType, out info);
 
-                       IComparer ic = null;
                        Type et = Enum.GetUnderlyingType (enumType);
-                       if (et == typeof (int))
-                               ic = int_comparer;
-                       else if (et == typeof (short))
-                               ic = short_comparer;
-                       else if (et == typeof (sbyte))
-                               ic = sbyte_comparer;
-                       else if (et == typeof (long))
-                               ic = long_comparer;
+                       SortEnums (et, info.values, info.names);
                        
-                       Array.Sort (info.values, info.names, ic);
                        if (info.names.Length > 50) {
                                info.name_hash = new Hashtable (info.names.Length);
                                for (int i = 0; i <  info.names.Length; ++i)
@@ -209,6 +200,21 @@ namespace System
                                global_cache [enumType] = cached;
                        }
                }
+               
+               internal static void SortEnums (Type et, Array values, Array names)
+               {
+                       IComparer ic = null;
+                       if (et == typeof (int))
+                               ic = int_comparer;
+                       else if (et == typeof (short))
+                               ic = short_comparer;
+                       else if (et == typeof (sbyte))
+                               ic = sbyte_comparer;
+                       else if (et == typeof (long))
+                               ic = long_comparer;
+                       
+                       Array.Sort (values, names, ic);
+               }
        };
 
        [Serializable]
index b27ffae5dc6a1a9d6326cc1e92ceb0a37b981ec0..11e6565ebe4e47859241d2dbc27b8ac1a98846ae 100644 (file)
@@ -511,11 +511,19 @@ namespace System {
 
                        var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
 
-                       string [] result = new string [fields.Length];
-                       for (int i = 0; i < fields.Length; ++i)
-                               result [i] = fields [i].Name;
-
-                       return result;
+                       string [] names = new string [fields.Length];
+                       if (0 != names.Length) {
+                               for (int i = 0; i < fields.Length; ++i)
+                                       names [i] = fields [i].Name;
+                                       
+                               var et = GetEnumUnderlyingType ();
+                               var values = Array.CreateInstance (et, names.Length);
+                               for (int i = 0; i < fields.Length; ++i)
+                                       values.SetValue (fields [i].GetValue (null), i);
+                               MonoEnumInfo.SortEnums (et, values, names);
+                       }
+
+                       return names;
                }
 
                static NotImplementedException CreateNIE () {
index 2c1ebbe5441da8294416f49ecd67ef0ea4812639..3b1532527363463ae69b9910c07984c67ed087db 100644 (file)
@@ -3489,6 +3489,22 @@ PublicKeyToken=b77a5c561934e089"));
                        Assert.AreEqual ("C", res [2], "#7");
                }
 
+               public enum OutOfOrderEnum : sbyte
+               {
+                       D = -1, C = 2, B = 1, A = 0
+               }
+                               
+               [Test]
+               public void GetEnumNamesSortsByUnsignedValue ()
+               {
+                       string[] names = typeof (OutOfOrderEnum).GetEnumNames ();
+                       Assert.AreEqual (4, names.Length);
+                       Assert.AreEqual ("A", names [0]);
+                       Assert.AreEqual ("B", names [1]);
+                       Assert.AreEqual ("C", names [2]);
+                       Assert.AreEqual ("D", names [3]);
+               }
+               
                [Test]
                public void GetEnumValues () {
                        try {