none
Flags korrekt anwenden RRS feed

  • Frage

  • Hallo,
    was bietet sich hier an?
    Ich habe einen Input und benötige einen Output.

         [Flags()]
            private enum ToDoModeInput
            {
                WP_CheckOne = 1,
                WP_CheckTwo = 2,
                WP_CheckThree = 4,
                WP_CheckFour = 8,
                WP_CheckFive = 16
            }

    Gebe ich den Input.

      ToDoModeInput myTestTodeCollectTheConfig = ToDoModeInput.WP_CheckOne | ToDoModeInput.WP_CheckTwo |
                                                       ToDoModeInput.WP_CheckFour | ToDoModeInput.WP_CheckFive;

    		ToDoModeInput myTestTodeCollectTheConfig = ToDoModeInput.WP_CheckOne | ToDoModeInput.WP_CheckTwo |
                                                       ToDoModeInput.WP_CheckFour | ToDoModeInput.WP_CheckFive;

    Grundlegende Prüfung

     bool validConfiguration = (((myTestTodeCollectTheConfig & ToDoModeInput.WP_CheckOne) == ToDoModeInput.WP_CheckOne) &&
                                           XXXXXXXX

    Jetzt muss ich sicherstellen, wenn WP_CheckThree gesetzt ist, muss! darf!! WP_CheckFour nicht gesetzt sein.

    Wie könnte man das elegant lösen?

    Am Rande, ich brauche da dann kein new operator, schon korrekt?

    Grüße Andy


    Dienstag, 26. Februar 2013 18:35

Antworten

  • Das kann ich dir so nicht sagen, das hängt von deinem Fall ab. Ich dachte an so etwas:

    namespace Test
    {
        using System;
    
        [Flags()]
        public enum ToDoModeInput
        {
            WP_CheckOne = 1,
            WP_CheckTwo = 2,
            WP_CheckThree = 4,
            WP_CheckFour = 8,
            WP_CheckFive = 16
        }
    
        public static class ToDoModeInputExtensions
        {
            public static bool IsSet(this ToDoModeInput toDoModeInput, ToDoModeInput flags)
            {
                return (toDoModeInput & flags) == flags;
            }
        }
    
        public class ToDoModeInputWrapper
        {
            private ToDoModeInput toDoModeInput;
    
            public ToDoModeInput Flags
            {
                get
                {
                    return this.toDoModeInput;              
                }
                set
                {
                    if (value.IsSet(ToDoModeInput.WP_CheckThree) && value.IsSet(ToDoModeInput.WP_CheckFour))
                    {
                        throw new ArgumentException("Not allowed.");
                    }
    
                    this.toDoModeInput = value;
                }
            }
    
            public ToDoModeInputWrapper(ToDoModeInput toDoModeInput)
            {
                this.Flags = toDoModeInput;
            }
    
            public static ToDoModeInputWrapper Create(ToDoModeInput toDoModeInput)
            {
                return new ToDoModeInputWrapper(toDoModeInput);
            }
    
            public override string ToString()
            {
                int value = 0;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckOne))
                    value += (int)ToDoModeInput.WP_CheckOne;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckTwo))
                    value += (int)ToDoModeInput.WP_CheckTwo;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckThree))
                    value += (int)ToDoModeInput.WP_CheckThree;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckFour))
                    value += (int)ToDoModeInput.WP_CheckFour;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckFive))
                    value += (int)ToDoModeInput.WP_CheckFive;
                return string.Format("{0}", value);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                ToDoModeInputWrapper f1 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckOne);
                ToDoModeInputWrapper f2 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckOne | ToDoModeInput.WP_CheckFour);
                Console.WriteLine(f1.ToString());
                Console.WriteLine(f2.ToString());
    
                ToDoModeInputWrapper f3 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckThree | ToDoModeInput.WP_CheckFour);
                Console.WriteLine(f3.ToString());
    
                Console.WriteLine("Done.");
                Console.ReadLine();
            }
        }
    }


    • Als Antwort markiert Andy Bauer Mittwoch, 27. Februar 2013 18:47
    Dienstag, 26. Februar 2013 21:43

Alle Antworten

  • Hast du dazu ein bischen Kontext? Auch wenn es sicher Anwendungsszenarien für Flags gibt, so sind sie doch in freier Wildbahn sehr selten.

    Elegant, naja, normal halt: Mit einer eigenen Klasse (ggf. Struktur). Sie dir auch mal BitConverter an.


    Dienstag, 26. Februar 2013 19:26
  • Hast du dazu ein bischen Kontext?

    Hallo Stefan,

    ja also ich habe ein KV-Diagramm - Input->Aktionen.

    Um nicht n-If else Anweisungen zu schreiben, dachte ich, prüfe eine Zahl,

    ob was gesetzt ist. Ähnlich wie es Microsoft mit den File Flags macht. Open, OpenWrite...

    Oder ist das wieder was anderes?

    Grüße Andy

    Dienstag, 26. Februar 2013 20:01
  • Das kann ich dir so nicht sagen, das hängt von deinem Fall ab. Ich dachte an so etwas:

    namespace Test
    {
        using System;
    
        [Flags()]
        public enum ToDoModeInput
        {
            WP_CheckOne = 1,
            WP_CheckTwo = 2,
            WP_CheckThree = 4,
            WP_CheckFour = 8,
            WP_CheckFive = 16
        }
    
        public static class ToDoModeInputExtensions
        {
            public static bool IsSet(this ToDoModeInput toDoModeInput, ToDoModeInput flags)
            {
                return (toDoModeInput & flags) == flags;
            }
        }
    
        public class ToDoModeInputWrapper
        {
            private ToDoModeInput toDoModeInput;
    
            public ToDoModeInput Flags
            {
                get
                {
                    return this.toDoModeInput;              
                }
                set
                {
                    if (value.IsSet(ToDoModeInput.WP_CheckThree) && value.IsSet(ToDoModeInput.WP_CheckFour))
                    {
                        throw new ArgumentException("Not allowed.");
                    }
    
                    this.toDoModeInput = value;
                }
            }
    
            public ToDoModeInputWrapper(ToDoModeInput toDoModeInput)
            {
                this.Flags = toDoModeInput;
            }
    
            public static ToDoModeInputWrapper Create(ToDoModeInput toDoModeInput)
            {
                return new ToDoModeInputWrapper(toDoModeInput);
            }
    
            public override string ToString()
            {
                int value = 0;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckOne))
                    value += (int)ToDoModeInput.WP_CheckOne;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckTwo))
                    value += (int)ToDoModeInput.WP_CheckTwo;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckThree))
                    value += (int)ToDoModeInput.WP_CheckThree;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckFour))
                    value += (int)ToDoModeInput.WP_CheckFour;
                if (this.toDoModeInput.IsSet(ToDoModeInput.WP_CheckFive))
                    value += (int)ToDoModeInput.WP_CheckFive;
                return string.Format("{0}", value);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                ToDoModeInputWrapper f1 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckOne);
                ToDoModeInputWrapper f2 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckOne | ToDoModeInput.WP_CheckFour);
                Console.WriteLine(f1.ToString());
                Console.WriteLine(f2.ToString());
    
                ToDoModeInputWrapper f3 = ToDoModeInputWrapper.Create(ToDoModeInput.WP_CheckThree | ToDoModeInput.WP_CheckFour);
                Console.WriteLine(f3.ToString());
    
                Console.WriteLine("Done.");
                Console.ReadLine();
            }
        }
    }


    • Als Antwort markiert Andy Bauer Mittwoch, 27. Februar 2013 18:47
    Dienstag, 26. Februar 2013 21:43
  • Hallo Stefan,

    ja das passt so schon mal. Frage beantwortet.
     > .... sie doch in freier Wildbahn sehr selten.
    Es geht, nicht desto trotz nur noch die Frage, sind
    Flags in dieser Art
    nicht so gebräuchlich?

    DANKE.

    Grüße Andy


    • Bearbeitet Andy Bauer Mittwoch, 27. Februar 2013 18:48 Format
    Mittwoch, 27. Februar 2013 18:47
  • Gebräuchlich schon, aber eher selten. Ich würde prinzipiell immer erstmal mit einfachen Klassen starten:

    class ToDo
    {
      public bool CheckOne { get; set; }
      public bool CheckTwo { get; set; }
      public bool CheckThree { get; set; }
      public bool CheckFour { get; set; }
      public bool CheckFive { get; set; }
    }

    Ob dann echte Flags basierend auf Enums Sinn machen hängt dann aber nur vom konkreten Fall ab. Z.B. Performance, Speicherverbrauch etc.

    Mittwoch, 27. Februar 2013 19:52