Laden...

Enum Flags mit Lambda Expressions in generischen Listen abfragen

Erstellt von pro vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.563 Views
P
pro Themenstarter:in
216 Beiträge seit 2006
vor 14 Jahren
Enum Flags mit Lambda Expressions in generischen Listen abfragen

(verwendetes Datenbanksystem): Lambda Expressions

Hallo zusammen,

Folgende Situation habe ich:

Ich habe eine generische Liste -> List<TestClass>

In dieser TestClass habe ich einen Enumerator:


    [Flags]
    [DataContract(Namespace = "urn:myNameSpace:v1")]
    public enum TestType 
    {
        [EnumMember]
        None = 0x0,

        [EnumMember]
        Test1= 0x1, 

        [EnumMember]
        Test2= 0x2, 
        
        [EnumMember]
        Test3= 0x4, 
        
        [EnumMember]
        Test4= 0x8,

        [EnumMember]
        All = 0xF
    };

Ich möchte nun in der generischen Liste mittels FindAll() nach bestimmten TestTypes suchen, die OR - verknüpft sind -> Test1 | Test2 (Inhalt des Filters).

Meine Abfrage sieht folgendermassen aus :


  List<TestClass> filtered = myList.FindAll(n => n.TestType == filter);

Leider hat die Liste filtered nach dem FindAll keine Einträge. Ist diese Abfrage mit den Flags überhaupt möglich (mittels Lambda Expressions)?

Vielen Dank für Eure Antworten.

Grüsse, pro

C
52 Beiträge seit 2010
vor 14 Jahren

Hoffentlich definierst du den Enum-Typ nicht in jeder TestClass 😃

Wenn TestClass.TestType so gesetzt wird:


TestClass tc = new TestClass();
tc.TestType = TestType.None | TestType.Test1;

dann wirst du über FindAll(n=> n.TestType == (TestType.None | TestType.Test1));
dieses Element auch finden. Dabei spielt es keine Rolle, in welcher Reihenfolge die Types verknüpft werden. FindAll(n=> n.TestType == (TestType.Test1| TestType.None)); findet das Element auch

FindAll(n=> n.TestType == (TestType.None)); wird dir das Element nicht wiederliefern, weil "tc.TestType = TestType.None ->|<- TestType.Test1;" kein oder ist, sondern ein "und". Somit wird es nicht gefunden.

P
pro Themenstarter:in
216 Beiträge seit 2006
vor 14 Jahren

Hallo chrismoe,

Vielen Dank für Deine Antwort.

Mein Sachverhalt ist ein wenig anders :


List<TestClass> myList = new List<TestClass>();
TestClass tc = new TestClass();
tc.TestType =  TestType.Test3;
myList.add(tc);
tc = new TestClass();
tc.TestType = TestType.Test4;
tc = new TestClass();
tc.TestType = TestType.Test5;

//ich möchte nun nur die TestClass Objekte bekommen, die Test4 ODER Test5 als TestType haben.

//Leider gibt mir filtered 0 TestClasses zurück. - Was mache ich falsch?
List<TestClass> filtered = myList.FindAll(n => n.TestType == (TestType.Test4 | TestType.Test5));

Vielen Dank für Eure Antworten.

Grüsse, pro

1.361 Beiträge seit 2007
vor 14 Jahren

Hi pro,

chrismoe hat ja schon angedeutet, dass die binäre Bitoperation "|" nicht mit dem logischen "||" verwechselt werden darf. Auch der Einsatz ist etwas anders.

Wie man mit den Bitoperationen richtig umgeht zeigt der Artikel Bitoperationen in C#.

Du musst also mit

(n.TestType & TestType.Test4) == TestType.Test4

darauf prüfen, ob n mindestens vom Typ Test4 ist.

Ich persönlich würde dafür eine kleine Hilfsfunktion einführen, sodass sich insgesamt ergibt:

public class TestClass 
{
	//...
	public bool HasType(TestType t)
	{
		return (this.TestType & t) == t;
	}
}

und du in der Lambda-Expression dann folgendes verwendet:

(n) => (n.HasType(TestType.Test4) || n.HasType(TestType.Test5))

beste Grüße
zommi

P
pro Themenstarter:in
216 Beiträge seit 2006
vor 14 Jahren

Hallo zommi,

Vielen Dank für deine Antwort.

So funktionierts...:-)

Grüsse, pro

C
52 Beiträge seit 2010
vor 14 Jahren
  
//Leider gibt mir filtered 0 TestClasses zurück. - Was mache ich falsch?  
List<TestClass> filtered = myList.FindAll(n => n.TestType == (TestType.Test4 | TestType.Test5));  
  

Vielen Dank für Eure Antworten.

Grüsse, pro

Wie Zommi sagte,
(n => n.TestType == (TestType.Test4 | TestType.Test5));
würde
tc.TestType = TestType.Test4 | TestType.Test5;
und
tc.TestType = TestType.Test5 | TestType.Test4;
finden.

Was du willst, ist (n=> ( n.TestTypeTest.Type4 || n.TestTypeTest.Type5));
also falsche Syntax/Semantik...