mayho33
Goto Top

C-Sharp Enum Bitweise prüfen in IF-ELSE-Anweisung

Hi @ All

Irgendwie stehe ich auf dem Schlauch. Ich dachte wenn man ein Enum mit dem [Flags]-Attribut ausstattet, kann man es anschließend bitweise überprüfen.
Funktioniert aber nicht. Kann mir jemand auf die Sprünge helfen wo der Fehler liegt?

hier ein Beispiel:
namespace Tester
{
    //[System.FlagsAttribute()]
    [Flags]
    public enum EnumTest
    {
        A = 0x01,
        B = 0x02,
        C = 0x04,
        D = 0x04
    }
    class Program
    {
        static void Main(string args)
        {
            EnumTest test = EnumTest.A;

            //Bsp. 1)
            //Fehler: Der |-Operator kann nicht auf den Operanden von Typ bool und EnumTest angewendet werden
            if (test == EnumTest.A | EnumTest.B)
            {
                //do somthing
            }

            //Bsp. 2)
            // wird einfach übersprungen
            if (test == (EnumTest.A | EnumTest.B))
            {
                //do somthing
            }

            //Bsp. 3)
            //funktioniert! ist aber umständlich, wenn man viele Werte prüfen will.
            // ich hätte es gerne wie in BSP. 1
            if (test == EnumTest.A || test == EnumTest.B)
            {
                //do somthing
            }
        }
    }
}

Danke für eure Hilfe!

Mayho

Content-Key: 579483

Url: https://administrator.de/contentid/579483

Printed on: June 13, 2024 at 18:06 o'clock

Member: emeriks
Solution emeriks Jun 16, 2020 updated at 09:56:34 (UTC)
Goto Top
Hi,
wenn eine Enum mit [Flags] versehen ist, dann kann man über HasFlag() prüfen.

if (test.HasFlag(EnumTest.A))
            {
                //do somthing
            }
if (test.HasFlag(EnumTest.A | EnumTest.B))
            {
                //do somthing
            }

E.

Edit:
Und wenn man tatsächlich eindeutige Werte hat, dann kann man ja auch einfach addieren und es bleibt eindeutig.
Mitglied: 144260
144260 Jun 16, 2020 updated at 10:54:48 (UTC)
Goto Top
Alternativ geht es auch mit den Bitweisen Operatoren zu arbeiten.
if ((test & EnumTest.A) != 0){

}
//usw.
//Fehler: Der |-Operator kann nicht auf den Operanden von Typ bool und EnumTest angewendet werden
Du kannst ja nicht Äpfel mit Birnen vergleichen face-smile.
Member: mayho33
mayho33 Jun 16, 2020 at 12:00:47 (UTC)
Goto Top
Zitat von @emeriks:

Hi,
wenn eine Enum mit [Flags] versehen ist, dann kann man über HasFlag() prüfen.

SPEZIAL!!
Habe mich echt schon gewundet weil bitweise testen ist ja keine Seltenheit:
var a = Regex.Match("MeinValue", "mein", RegexOptions.IgnoreCase | RegexOptions.Multiline).Value;  

Danke!
Member: mayho33
mayho33 Jun 16, 2020 updated at 12:31:15 (UTC)
Goto Top
Zitat von @144260:

Alternativ geht es auch mit den Bitweisen Operatoren zu arbeiten.
> if ((test & EnumTest.A) != 0){
> 
> }
> //usw.
> 
Fehler: Der |-Operator kann nicht auf den Operanden von Typ bool und EnumTest angewendet werden
Du kannst ja nicht Äpfel mit Birnen vergleichen face-smile.

Ich arbeite doch mit bitweisen Operatoren (siehe):
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operat ... //

Und eigentlich vergleiche ich keine Äpfel mit Birnen. Ich vergleiche Farben von Äpfeln und da wollte ich nur wissen ob ich einen roten Apfel oder einen gelben Apfel habe.

Wenn man konstant der Logik einer IF-Else-Anweisung folgt, sollte diese immer nur true oder false liefert. if(GeradeAngenommeneApfelFarbe == Rot | Gelb) sollte also true oder false sein und nicht Ähhhhhhh....Warte! Ich kann das Schleifchen nur um Orange Bälle wickeln!!

if(1 == 2) ==> false
if(3 == 2 + 1) ==> true
if(List<t> != null) ==> geht
if(List<t>.count() > 0) == geht
if(string.isNullOrEmpty(valueA)) geht

Warum also nicht [Flag]A == [Flag]X | [Flag]Z ??

Das erinnert mich ein klein wenig an VBScript und Instr(). Da wird der Index des Vorkommens geliefert. Ist das Suchwort zufällig an erster Stelle bekommt man 0 obwohl positiv. Kein Logik-Fehler aber trotzdem ###e.
Mitglied: 144260
144260 Jun 16, 2020 updated at 12:41:18 (UTC)
Goto Top
Warum also nicht [Flag]A == [Flag]X | [Flag]Z ??

Sagt die Fehlermeldung doch schon. face-wink
Ich arbeite doch mit bitweisen Operatoren (siehe):
Aber nicht in der richtigen Art und Weise im Vergleich.
Member: mayho33
mayho33 Jun 16, 2020 at 13:49:02 (UTC)
Goto Top
Zitat von @144260:

Warum also nicht [Flag]A == [Flag]X | [Flag]Z ??

Sagt die Fehlermeldung doch schon. face-wink

Sorry, aber das kann ich nicht als Antwort gelten lassen. Der Kompiler kann es nicht, schon klar! Aber ist das logisch? Hast du dir den Link schon angeschaut? Da wird es nämlich genauso beschrieben. Doch der Kompiler schreit:

logcal or

ein weiteres Beispiel:
[Flag]A = A
[Flag]B = B

if([Flag]A == [Flag]X) => false
if([Flag]A != [Flag]X) => true

aber..
if(Flag]A == [Flag]X | [Flag]A) => Gewurschtel
if(Flag]A == ([Flag]X | [Flag]A)) => wird nicht ausgewertet

Wo ist da die Logik versteckt?

Wenn du es nicht weißt, kann ich damit leben. Ich weiß es ja auch nicht. Aber bitte (sorry) nicht schlaumeiern sondern erklären!

Ich arbeite doch mit bitweisen Operatoren (siehe):
Aber nicht in der richtigen Art und Weise im Vergleich.

Warum schreibt es MS dann in seiner C#-Reference so hin?
Mitglied: 144260
Solution 144260 Jun 16, 2020 updated at 14:53:44 (UTC)
Goto Top
Zitat von @mayho33:
ein weiteres Beispiel:
if(Flag]A == [Flag]X | [Flag]A) => Gewurschtel
Hier müssen Klammern um die OR verknüpften Flags, das ist ein syntaktischer Fehler.
if(Flag]A == ([Flag]X | [Flag]A)) => wird nicht ausgewertet
Wo ist da die Logik versteckt?
Hier sind die Klammern zwar gesetzt da aber das Ergebnis dieser ist ja nicht das gewollte weil hier ja das Ergebnis der Bitweisen Operation in den Klammern berechnet wird.

Beispiel
enum Test {
     A = 0x1,
     B = 0x2,
     C = 0x4
 }
Test t = Test.A;
Gesprochen
t = BINÄR (0 0 0 0 0 0 0 1) = 1

(Test.A | Test.B) = BINÄR(0 0 0 0 0 0 0 1) OR BINÄR(0 0 0 0 0 0 1 0) = 3
Also macht der IF-Vergleich daraus
1 == 3
Und 1 ist nun mal nicht gleich 3.

logcal or
Ja ist vielleicht etwas unglücklich/missverständlich ausgedrückt.
Member: mayho33
mayho33 Jun 20, 2020 at 12:13:45 (UTC)
Goto Top
Dein Beispiel ist logisch nachvollziehbar.

Danke dass du dir die Mühe gemacht hast!