Laden...

String in Enum Convertieren - Funktioniert im Debug aber nicht im Release Modus.

Erstellt von trib vor 4 Jahren Letzter Beitrag vor 4 Jahren 981 Views
T
trib Themenstarter:in
708 Beiträge seit 2008
vor 4 Jahren
String in Enum Convertieren - Funktioniert im Debug aber nicht im Release Modus.

Hallo zusammen,

ich übergebe eine Farbe als string an meine App.
Dort wird aus dem Enum System.Drawing.Color die passende Farbe herausgesucht und gesetzt.
Das funktioniert, sofern die App als Debug bereitgestellt wird.
Wird sie als Release kompiliert, erhalte ich folgende Meldung:

Fehlermeldung:
Type provided must be an Enum. Parameter name: enumType

Der entsprechende Code:
(Es handelt sich dabei noch um ein Relikt, welches Win CE kompatibel ist. Es gibt sicherlich mittlerweile elegantere Umsetzungen)

    public static class Colors
    {
        public static readonly Dictionary<Color, string> ColorNames = new Dictionary<Color, string>();
        public static readonly Dictionary<string, Color> ColorValues = new Dictionary<string, Color>();

        static Colors()
        {
            var fi = typeof(Color).GetFields(BindingFlags.Static | BindingFlags.Public);
            for (var iEnum = 0; iEnum < fi.Length; iEnum++)
            {
                AddColor(fi[iEnum].Name, (Color)fi[iEnum].GetValue(null));
            }
            var pi = typeof(Color).GetProperties(BindingFlags.Static | BindingFlags.Public);
            for (var iEnum = 0; iEnum < pi.Length; iEnum++)
            {
                if (pi[iEnum].PropertyType == typeof(Color))
                {
                    AddColor(pi[iEnum].Name, (Color)pi[iEnum].GetValue(null, null));
                }
            }
            pi = typeof(SystemColors).GetProperties(BindingFlags.Static | BindingFlags.Public);
            for (var iEnum = 0; iEnum < pi.Length; iEnum++)
            {
                if (pi[iEnum].PropertyType == typeof(Color))
                {
                    AddColor(pi[iEnum].Name,(Color)pi[iEnum].GetValue(null, null));
                }
            }
        }

        private static void AddColor(string name, Color color)
        {
            if (ColorNames.ContainsKey(color))
                return;
            //Not supported:
            if (color == Color.Transparent)
                return;
            ColorNames.Add(color, name);
            ColorValues.Add(name, color);
        }

        public static string ColorToString(Color color)
        {
            string name;
            if (!ColorNames.TryGetValue(color, out name))
            {
                name = "Empty";
            }
            return name;
        }

        public static Color StringToColor(string colorName)
        {
            Color color;
            if (ColorValues.TryGetValue(colorName, out color))
                return color;
            if (ColorValues.TryGetValue(string.Format("Color [{0}]", colorName), out color))
                return color;
            try
            {
                color = (Color)Enum.Parse(typeof(Color), colorName, true);
            }
            catch (Exception ex)
            {
                MessageMgt.CaptureError(ex.Message, "Color " + colorName);
                color = Color.Empty;
            }
            return color;
        }
    }

Der Fehler tritt bei

Enum.Parse(typeof(Color), colorName, true);

auf. Z.B. wenn man "Green" oder "AliceBlue" übergibt.

Der Debugger hilft mir dabei leider nicht weiter, da der Fehler schließlich nur auftritt, wenn ich ohne Debug-Informationen kompiliere.

Hätte jemand eine Idee woran das liegen könnte?
Oder wie ich es selbst herausfinden kann?

709 Beiträge seit 2008
vor 4 Jahren

Ist System.Drawing.Color nicht eigentlich ein struct?

T
2.224 Beiträge seit 2008
vor 4 Jahren

@pinki
Korrekt, die Farben dort sind nur static Color Instanzen mit den festen Farbwerten.

Doku Color
Color.Green

Ergo ist die forcierte Umwandlung zu Enum falsch und knallt immer.

Nachtrag:
Einen Teil des Code kannst du auch durch die static Methoden von Color umsetzen.
Z.B. kannst du StringToColor mit Color.FromName umsetzen, wenn du die Standard Farben verwendest.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
trib Themenstarter:in
708 Beiträge seit 2008
vor 4 Jahren

Das Problem liegt offenbar nicht an der Umwandlung des Enums.
Wie T-Virus schon schreibt, würde das nie funktionieren!
++
Im Umkehrschluss bedeutet das aber:++
Im Debug-Modus füllt der Konstruktor die Dictionary´s mit Werten. Deshalb läuft der Code gar nicht erst an diese Stelle.
In Release nicht, weshalb der cast fehlschlägt!

Die Frage wäre jetzt nach wie vor: Warum?

Anstelle des Cast auf Color habe ich nun

Color.FromName(colorName)

verwendet.
Funktioniert sofort und kann nach wie vor einfach mit einer Kompileranweisung (#if WindowsCE) für Windows CE kompilliert werden.

Das Problem ist also gelöst, danke an Euch beide! Interessieren würde mich die Unterscheidung aber trotzdem 😃

[EDIT]
Kopiert man den Code aus dem Xamarin-Projekt in eine Konsolenanwendung funktioniert er sowohl als Debug, als auch per Release.
Hängt also definitiv mit Xamarin zusammen, wo ich den Beitrag ursprünglich eingestellt habe.