J. W. schrieb:
> Ich möchte eine If-Abfrage mit zwei or-conditions vereinfachen.
> Damit ich innerhalb des if-branches noch unterscheiden kann, welcher der
> beiden werte zutrifft, halte ich diesen Wert in einer Variablen fest
> (sopt).
> In C habe ich das schon immer so gemacht.
Da ist das zwar auch nicht schön, aber noch vertretbar weil man da dann
innerhalb des if-blocks nur einen Pointer und kein ganzes Objekt nochmal
vergleichen muss.
> Mit Mono-Projekt in C# funktioniert es.
> Frage: Funktioniert das generell (d.h. auch in Visual Studio)?
Ja.
> Ist sowas sauber programmiert?
Nein. Einen string zu benutzen ist mit Sicherheit nicht sauber
programmiert. Konkret sieht das dann nämlich so aus:
1 | //string test = "123abc123";
|
2 | IL_000c: ldstr "123abc123"
|
3 | IL_0011: stloc.0
|
4 |
|
5 | //string prefix = null;
|
6 | IL_0012: ldnull
|
7 | IL_0013: stloc.1
|
8 |
|
9 | //if (test.StartsWith(prefix = "abc") ||
|
10 | // test.StartsWith(prefix = "123"))
|
11 | IL_0014: ldloc.0
|
12 | IL_0015: ldstr "abc"
|
13 | IL_001a: dup
|
14 | IL_001b: stloc.1
|
15 | IL_001c: callvirt instance bool [mscorlib]System.String::StartsWith(string)
|
16 | IL_0021: brtrue.s IL_0032
|
17 |
|
18 | IL_0023: ldloc.0
|
19 | IL_0024: ldstr "123"
|
20 | IL_0029: dup
|
21 | IL_002a: stloc.1
|
22 | IL_002b: callvirt instance bool [mscorlib]System.String::StartsWith(string)
|
23 | IL_0030: brfalse.s IL_006d
|
24 |
|
25 | // {
|
26 | // if (prefix == "abc")
|
27 | IL_003d: ldloc.1
|
28 | IL_003e: ldstr "abc"
|
29 | IL_0043: call bool [mscorlib]System.String::op_Equality(string, string)
|
30 | IL_0048: brfalse.s IL_0055
|
31 |
|
32 | // if (prefix == "123")
|
33 | IL_0055: ldloc.1
|
34 | IL_0056: ldstr "123"
|
35 | IL_005b: call bool [mscorlib]System.String::op_Equality(string, string)
|
36 | IL_0060: brfalse.s IL_006d
|
Visual Studio mit Standardeinstellungen optimiert das also schon mal
nicht. Innerhalb des if-blocks werden die Strings nochmal neu auf den
Stack gepusht und dann wird eine lib-Funktion für den Vergleich
aufgerufen.
Schöner und effizienter geht es so:
1 | bool b_pre_abc = test.StartsWith("abc"),
|
2 | b_pre_123 = test.StartsWith("123");
|
3 |
|
4 | if (b_pre_123 || b_pre_abc)
|
5 | {
|
6 | MessageBox.Show("Match");
|
7 |
|
8 | if (b_pre_abc)
|
9 | ...
|
10 | if (b_pre_123)
|
11 | ...
|
12 | }
|
Das sieht dann nämlich innerhalb des if-blocks schon wesentlich
schlanker aus:
1 | //if (b_pre_abc)
|
2 | IL_0095: ldloc.2
|
3 | IL_0096: brfalse.s IL_00a3
|
4 |
|
5 | //if (b_pre_123)
|
6 | IL_00a3: ldloc.3
|
7 | IL_00a4: brfalse.s IL_00b1
|
Man spart sich also zwei library calls, viele Stringoperationen und
gewinnt auch noch Lesbarkeit.