Laden...

Suche Kurzform für if-Abfrage mit mehreren Bedingungen

Erstellt von Elias1994 vor 7 Jahren Letzter Beitrag vor 7 Jahren 5.719 Views
E
Elias1994 Themenstarter:in
54 Beiträge seit 2015
vor 7 Jahren
Suche Kurzform für if-Abfrage mit mehreren Bedingungen

Hallo,

ich suche eine Kurzform für eine if-Abfrage, da mein Code dadurch bisher sehr unleserlich ist. Das muss doch kürzer gehen oder eine andere Strategie geben:


public enum testedConnection{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} //enum

if (dropDown_Tested_Device.Value == testedConnection.a || dropDown_Tested_Device.Value == testedConnection.b|| dropDown_Tested_Device.Value == testedConnection.c || dropDown_Tested_Device.Value == testedConnection.d || dropDown_Tested_Device.Value == testedConnection.e || dropDown_Tested_Device.Value == testedConnection.f || dropDown_Tested_Device.Value == testedConnection.g || dropDown_Tested_Device.Value == testedConnection.h|| dropDown_Tested_Device.Value == testedConnection.i|| dropDown_Tested_Device.Value == testedConnection.j|| dropDown_Tested_Device.Value == testedConnection.k || dropDown_Tested_Device.Value == testedConnection.q || dropDown_Tested_Device.Value == testedConnection.r|| dropDown_Tested_Device.Value == testedConnection.s || dropDown_Tested_Device.Value == testedConnection.t || dropDown_Tested_Device.Value == testedConnection.u)
{//do something
}
W
955 Beiträge seit 2010
vor 7 Jahren

Was willst du mit dem Enum eigentlich erreichen?

E
Elias1994 Themenstarter:in
54 Beiträge seit 2015
vor 7 Jahren

Was willst du mit dem Enum eigentlich erreichen?

Mit dem Enum wird eine DropdownListe gefüllt (WindowsForms). Der User kann dann einen Eintrag aus der Liste auswählen.

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo Elias1994,

suchst du sowas wie

Enum.IsDefined

Gruss

Coffeebean

E
Elias1994 Themenstarter:in
54 Beiträge seit 2015
vor 7 Jahren


>

Nicht ganz.

Wenn sowas gehen würde wäre das Ganze einfacher:

if (dropDown_Tested_Device.Value == a || b || c || d ...)
 {//do something
 } 
A
31 Beiträge seit 2009
vor 7 Jahren

Hallo Elias1994,

vieleicht hilft das hier weiter:

testedConnection tc = testedConnection.a;
	
	tc = testedConnection.z;
	
	if (Enum.GetValues(typeof(testedConnection))
					.Cast<testedConnection>()
					.Where(x => x <= testedConnection.u)
					.Contains(tc))
	{
		Console.WriteLine (	"gefunden");
	}
	else
	{
		Console.WriteLine ("nicht gefunden");
	}


Viele Grüße

1.040 Beiträge seit 2007
vor 7 Jahren

Du könntest das if umdrehen und die anderen Werte prüfen (die wohl deutlich weniger sind).

Oder schreibe dir eine Methode, die prüft, ob der Wert vorkommt:

private bool CheckEnum(testedConnection currentValue, params testedConnection[] possibleValues);

@Anakin Skywalker: Was genau macht das? 🤔

J
251 Beiträge seit 2012
vor 7 Jahren

Mein erster Gedanke



//Falls Value nicht int ist (theo. besseres als blind cast anwenden)
 int x = (int)dropDown_Tested_Device.Value

//Wenn nicht verzählt :D
if(x < 11 || (x > 15 && x < 21))



1.029 Beiträge seit 2010
vor 7 Jahren

Hi,

nun ja - um das zu verkürzen würde ich:
a) "dropDown_Tested_Device.Value" in eine kürzere, temporäre Variable packen
b1) Eine deutlich kürzere switch-Anweisung schreiben, die im default ok sagt und andernfalls eben nein (das lässt sich dann noch damit abkürzen, dass man einzelne breaks weglässt
b2) Die Methode von p!lle verwendet
b3) Da dein Enum ja eine Zahl ist lassen sich auch damit sehr einfach Prüfungen anstellen

Zu b1:


static bool TestEnumWithSwitch(testedConnection c)
{
	switch (c)
	{
		case testedConnection.l:
		case testedConnection.m:
		case testedConnection.n:
		case testedConnection.o:
		case testedConnection.p:
			return false;
		//...
		default:
			return true;
	}
}

Zu b2:


static bool TestEnumWithParams(testedConnection c, IEnumerable<testedConnection> allowedValues )
{
	return allowedValues.Count(v => v == c) == 1;
}

static IEnumerable<testedConnection> GetDeinSehrSinnvollerName()
{
	return new[]
	{
		testedConnection.a, testedConnection.b, testedConnection.c, testedConnection.d, testedConnection.e,
		testedConnection.f, testedConnection.g, testedConnection.h, testedConnection.i, testedConnection.j,
		testedConnection.k, testedConnection.q, testedConnection.r, testedConnection.s, testedConnection.t,
		testedConnection.u
	};
}

LG

3.003 Beiträge seit 2006
vor 7 Jahren

@Pille: selektiert alle möglichen Werte des Enums und prüft dagegen.


//alle werte des Enums - EDIT: in diesem speziellen Fall ist Cast<> schneller. OfType ist aber eine Alternative.
var enums = Enum.GetValues(typeof(testedConnection)).OfType<testedConnection>();

//...vor testedConnection.u
enums = enums.Where(p => p <= testedConnection.u);

//hat das Objekt dropDown_Tested_Device.Value einen der Werte des Enums?
var isValid = enums.Any(p => p == dropDown_Tested_Device.Value);

//geht auch als Einzeiler natürlich.

LaTino
EDIT2: ich würde hier in der Enumeration diskrete Werte vergeben und direkt per < prüfen. Ist am simpelsten.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

1.040 Beiträge seit 2007
vor 7 Jahren

Frage falsch formuliert. 😁 Mich hatten eher die ersten beiden Zeilen im Schnipsel verwundert. Aber eine gute Alternative, Where müsste nur erweitert werden...

3.003 Beiträge seit 2006
vor 7 Jahren

Frage falsch formuliert. 😄 Mich hatten eher die ersten beiden Zeilen im Schnipsel verwundert. Aber eine gute Alternative, Where müsste nur erweitert werden...

Jetzt erst gesehen...um. Ähm. Keine Ahnung 😉.

Hatte auch nicht bemerkt, dass da alle zwischen k und q auch rausfallen. In dem Fall, anstatt das Where aufzubohren:


   //ändert gar nichts am Code, macht aber das Zuordnen leichter.
    public enum TestedConnection { a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, i = 9, j = 10, k = 11, l = 12, m = 13, n = 14, o = 15, p = 16, q = 17, r = 18, s = 19, t = 20, u = 21, v = 22, w = 23, x = 24, y = 25, z = 26 }
 
  var myEnum = dropDown_Tested_Device.Value;
  if(myEnum < TestedConnection.l || TestedConnection.p < myEnum && myEnum < TestedConnection.v )

Also, was Jamikus schrieb. Besser lesbar wird es nicht mehr, fürchte ich.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

A
31 Beiträge seit 2009
vor 7 Jahren

@p!lle: die ersten beiden Zeilen hatte ich so im LinqPad zum testen;)

@LaTino: Any ist schneller als Contains, oder?

16.842 Beiträge seit 2008
vor 7 Jahren

Any ist immer eine Enumeration, Contains verwendet je nach Collection Hashes, Binary Search oder B-Tree. Any ist immer O(n) während Contains bei Listen ebenfalls O(n) ist aber bei nem HashSet O(1).
Daher wird Contains in den meisten Fällen schneller sein als ein Any, das zudem auch immer ein Vergleich durchführen muss.

3.003 Beiträge seit 2006
vor 7 Jahren

@LaTino: Any ist schneller als Contains, oder?

Ja - schneller geschrieben 😉. Contains() ist wie Any, nur dass das Prädikat (der Delegat im Argument) direkt der EqualityComparer<>.Default.Compare ist. (Zur Klarstellung: die beiden rufen sich NICHT gegenseitig auf, sondern enumerieren die Collection bis zum ersten Treffer. Was ein Treffer ist, bestimmt bei Any() das Prädikat, und bei Contains eben die Compare()-Methode des benutzten EqualityComparers).

Die Ausführungen von Abt sind für die Enumerable.Any und Enumerable.Contains-Methoden nicht ganz korrekt.

Performancetechnisch kein Unterschied, soweit ich weiß. Beides jedoch schneller als Count() > 0.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

16.842 Beiträge seit 2008
vor 7 Jahren

Die Ausführungen von Abt sind für die Enumerable.Any und Enumerable.Contains-Methoden nicht ganz korrekt.

Dann korrigiere sie bitte.
Nur zu sagen, sie sind falsch, bringt keinem was. Würde zudem gerne wissen, was falsch ist - nicht, dass ich nochmal was falsches verbreite.

3.003 Beiträge seit 2006
vor 7 Jahren

Dachte, das hätte ich 😉.

Die Überladungen von Contains() in bestimmten IEnumerable-Implementierungen sind schneller als Enumerable.Any(), daher kann es bei diesen (bspw HashSet) Sinn machen, Contains zu nutzen. Für Prädikate, die auf Gleichheit prüfen, ist die Performance identisch, weil der erzeugte Code identisch ist. Für Any()-Aufrufe mit anderen Prädikaten ist Any schneller (Any(p => true) als einfachstes Beispiel) oder langsamer (Any(p => { Thread.Sleep(2000); return p == compareValue); }) als schlimmes Beispiel).

Einfache Vergleiche der beiden Methoden auf nicht-spezialisierten Enumerationen (HashSet zB benutze ich relativ selten) sollten kaum Unterschiede zeigen.

Bessere Antwort als ich sie geben könnte: http://stackoverflow.com/questions/17302096/linq-performance-any-vs-contains

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

16.842 Beiträge seit 2008
vor 7 Jahren

Okay. Also so ziemlich das gleiche, was ich gesagt habe 😃
Contains prüft ebenfalls bei Listen auf true (wie Any). Beide O(n).

3.003 Beiträge seit 2006
vor 7 Jahren

Ich bezog mich auf die Aussage "ein Any, das zudem auch immer ein Vergleich durchführen muss", denn das muss Contains in unserem Fall hier auch. Auf IEnumerables, wo es Sinn macht, gibt es eine extra-Implementierung, und die natürlich nur, weil sie eben schneller ist (sonst bräuchte man sie nicht). Deshalb "nicht ganz" 😃.

@Anakin
ist zum großen Teil auch persönliche Gewohnheit, wie auch schon bei OfType<> vs. Cast<>, ich habe ehrlich gesagt beim Tippen nicht wirklich drüber nachgedacht.
Ich benutze Any() häufiger, weil ich häufiger komplexere Sachverhalte damit prüfe als Gleichheit und weil ich es deutlicher finde. Aber das bin nur ich 😉. Übrigens ist die Wahl meist nicht zwischen Any() und Contains(), sondern Any() und Count() > 0. Und da ist die Antwort eindeutiger.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

A
31 Beiträge seit 2009
vor 7 Jahren

@LaTino, @Abt: Danke für die Erklärungen. (y)