Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
String in Enum Convertieren - Funktioniert im Debug aber nicht im Release Modus.
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 689

Themenstarter:

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

beantworten | zitieren | melden

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:
Fehler
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?
private Nachricht | Beiträge des Benutzers
pinki
myCSharp.de - Member

Avatar #avatar-4072.jpg


Dabei seit:
Beiträge: 695
Herkunft: OWL

beantworten | zitieren | melden

Ist System.Drawing.Color nicht eigentlich ein struct?
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1795
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

@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
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
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.
private Nachricht | Beiträge des Benutzers
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 689

Themenstarter:

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers