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
Elegante Lösung für If Abfrage einer Variable auf mehrere zulässige Werte
ludden
myCSharp.de - Member



Dabei seit:
Beiträge: 56

Themenstarter:

Elegante Lösung für If Abfrage einer Variable auf mehrere zulässige Werte

beantworten | zitieren | melden

Hallo,
ich hoffe ich bin hier richtig, eigentlich ist es keine große Frage aber einen "kurze Frage kurze Antwort Thread" habe ich nicht gefunden.

Jetzt zu meinem Problem:
Seid kurzem Programmiere ich berufsbedingt wieder und bin heute über ein Problem gestoßen über das ich schon seit Jahren nachdenke.

Ich hab eine Variable die versch. Werte annehmen kann. Normalerweise schreit sowas ja nach einem switch case, aber manchmal möchte ich sowas machen


int i = gibMirIrgendEineZahl();
if(i == 1 || i == 2 || i== 4000 || i == 1337 || i = 100)
{
      foo();
}
Sehr unübersichtlich und blöd zu ändern.

Also für jede dieser Bedingungen genau die gleiche Aktion ausführen, weshalb ich einen switch irgendwie als unnötig empfinde er würde ja sowieso so aussehen:


switch(i)
{
case 1 : foo;break;
case 2 : foo;break;
case 4000 : foo;break;
case 1337 : foo;break;
case 100 : foo;break;
}
Das nimmt mir allerdings zuviel Platz weg und extra eine Region definieren halte ich auch für übertrieben.


Jetzt drängt es mich irgendwie sowas zu machen(Achtung pseudocode):


if(i in [1,2,4000,1337,100])
{
      foo();
}

was meiner Meinung nach sehr elegant und kurz wäre. Gibt es sowas und ich bin einfach noch nicht darüber gestolpert? Ich glaub in Python gibt es so ein Konstruckt.
private Nachricht | Beiträge des Benutzers
Darth Maim
myCSharp.de - Member



Dabei seit:
Beiträge: 230

beantworten | zitieren | melden

Hallo ludden,

zum einen guck die mal diesen Thred an, den wir hier vor kurzem hatten: if-schleife mit vielen String-Bedingungen abkürzen....

Zum anderen kann man die switch-Anweisung folgendermaßen verkürzen:

switch(i) {
  case 1:
  case 2:
  case 4000:
  case 1337:
  case 100:
    foo();
    break;
}

Dein unteres Beispiel lässt sich so umsetzen:

int[] bla = new int[] { 1, 2, 4000, 1337, 100 };

if(bla.Contains(i))
  foo();

Edit: Beziehungsweise, näher an deinem Beispiel, wenn auch meiner Meinung nach nicht übersichtlicher:

if((new int[] { 1, 2, 4000, 1337, 100 }).Contains(i))
  foo();

Ich hoffe ich konnte dir helfen,

DarthMaim
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Darth Maim am .
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Oder du benutzt eine Erweiterungsmethode:


public static class IsInExtensions
{
	public static bool IsIn<T>(this T value,IEnumerable<T> enumerable)
	{
		return enumerable.Contains(value);
	}

	public static bool IsIn<T>(this T value,params T[] enumerable)
	{
		return enumerable.Contains(value);
	}
}

Aufruf dann wie folgt:


if (i.IsIn(1,2,4000,1337,100))
{ ... }
oder


if (i.IsIn(new[] { 1,2,4000,1337,100 }))
{ ... }

Gruß,
dN!3L
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Schnelle Alternative wäre ein HashSet<int>.
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Zitat
weshalb ich einen switch irgendwie als unnötig empfinde er würde ja sowieso so aussehen:

Warum nicht so:

switch(i)
{
case 1:
case 2:
case 4000:
case 1337:
case 100:
    foo();
    break;
}

Allerdings ist der Vorschlag von ujr für sehr viele Werte deutlich schneller, sofern das HashSet wiederverwendet wird.

Und wiederverwendet heißt meißt statische Variable!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
ludden
myCSharp.de - Member



Dabei seit:
Beiträge: 56

Themenstarter:

beantworten | zitieren | melden

Zitat von Floste
Allerdings ist der Vorschlag von ujr für sehr viele Werte deutlich schneller, sofern das HashSet wiederverwendet wird.

Und wiederverwendet heißt meißt statische Variable!

Brauchs eigentlich nur 1x, aber die Idee von Dniel find ich ganz nett :)
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo,
Zitat
aber die Idee von Dniel find ich ganz nett :)

Ja, nette Idee. Aber ich sehe keinen wirklichen Sinn darin eine solche Methode zu schreiben. Sie kehrt im Gegensatz zu Contains lediglich Aufrufinstanz und Parameter um. Sparen tut man dadurch nix, weil man mit denselben Objekten auch direkt Contains verwenden kann. Und zwar immer.

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
der-schlingel
myCSharp.de - Member

Avatar #avatar-3239.jpg


Dabei seit:
Beiträge: 820
Herkunft: Österreich/Wien

beantworten | zitieren | melden

[offtopic]Dem gegenüber steht aber die gute Lesbarkeit insofern finde ich das schon ganz nett was dEN!3l da gemacht hat.

Ist natürlich Geschmackssache ob man sich die extra Arbeit für die deklarative Schreibart antut.[/offtopic]
As a man thinketh in his heart, so he is.
- Jun Fan
Es gibt nichts Gutes, außer man tut es.
- Erich Kästner
Krawutzi-Kaputzi
- Kasperl
private Nachricht | Beiträge des Benutzers
m0rius
myCSharp.de - Member

Avatar #avatar-3125.png


Dabei seit:
Beiträge: 1043

beantworten | zitieren | melden

Hallo MarsStein,

ganz so einfach ist es nicht — so lässt sich zum Beispiel dN!3Ls zweite Erweiterungsmethode, die params nutzt, nicht ganz trivial umdrehen, sodass Contains() verwendet werden kann:

if (i.IsIn(1, 2, 4000, 1337, 100))
{ 
    /* ... */
}
Das händische Äquivalent wäre

if (new int[] { 1, 2, 4000, 1337, 100 }.Contains(i))
{ 
    /* ... */
}
Ich halte dN!3Ls Variante auch für deutlich lesbarer! Gerade den Aspekt Lesbarkeit kommt häufig zu kurz und sollte meiner Meinung nach nicht unterschätzt werden.

m0rius
Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg
private Nachricht | Beiträge des Benutzers
MarsStein
myCSharp.de - Experte

Avatar #avatar-3191.gif


Dabei seit:
Beiträge: 3430
Herkunft: Trier -> München

beantworten | zitieren | melden

Hallo zusammen,

gerade im Bezug auf Lesbarkeit finde ich die Variante nicht so gut, weil sie an dem im Framework vorhandenen und durchgängig benutzten Contains vorbei die Methode genau anders rum implementiert.
Auch wird bei der Version mit params für den Quellcodeleser nicht klar, dass hier implizit eine Collection erstellt wird, was durch den ungewohnten Methodennamen nicht besser wird.

-> Man sieht einfach nicht so gut was passiert (meine persönliche Meinung)

Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von ludden & der-schlingel
Dniel [...] dEN!3l
dN!3L

Meine Methode hat auch einzig den Zweck, die Parameterreihenfolge zu tauschen. Je nach Anwendungsfall liest es sich so besser (Stichwort Yoda Conditions). Und in Anlehnung z.B. an den SQL-Befehl i IN (1,23,456).

Gruß
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dN!3L am .
private Nachricht | Beiträge des Benutzers

Moderationshinweis von herbivore (13.04.2011 - 10:30:29):

Bitte streitet euch nicht um des Kaisers Bart!

Jeder kann selbst entscheiden, was er nutzen möchte.

MathiasM
myCSharp.de - Member



Dabei seit:
Beiträge: 6

beantworten | zitieren | melden

Was hier noch nicht erwähnt wurde: in VB.Net gibts noch den Befehl IIF, klappt allerdings nur mit 2 Werten aber den setze ich gerne bei Return-Anweisungen ein, spart ein paar Zeilen :-)

Wie der in C# heißt weiß ich allerdings leider nicht.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MathiasM am .
private Nachricht | Beiträge des Benutzers
Coder007
myCSharp.de - Member



Dabei seit:
Beiträge: 1249

beantworten | zitieren | melden

OMG. Ein Grund mehr, VB nicht zu verwenden.

In Sprachen mit C Syntax macht man das mit ?. Hat aber nichts mit der ursprünglichen Frage zu tun.
private Nachricht | Beiträge des Benutzers
pdelvo
myCSharp.de - Member

Avatar #avatar-3354.png


Dabei seit:
Beiträge: 1407

beantworten | zitieren | melden

return a > b ? 1 : 2;

jetzt ist aber gut hier mit offtopic. Sonst gibts haue von herbivore
private Nachricht | Beiträge des Benutzers