Autor Beitrag
erfahrener Neuling
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Di 17.05.16 13:04 
Hallo,

gibt es eine Möglichkeit, eine Bedingung ungefähr nach folgendem Schema abzufragen
ausblenden C#-Quelltext
1:
if (myString == ("abc" || "123" || "xyz")) {...}					
anstatt
ausblenden C#-Quelltext
1:
if (myString == "abc" || myString == "123" || myString == "xyz") {...}					

Bin gespannt auf eure Antworten
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 17.05.16 13:13 
ausblenden C#-Quelltext
1:
if ((new string[] { "abc""123""xyz" }).Contains(myString))					


Nebenbei solltest du dich an der Stelle aber fragen was für einen Vergleich du genau willst.
Bei strings muß man sich immer fragen mit welchen Culture Einstellungen das gerade passiert und ob man casesensitiv/insensitiv prüfen will.

Die verschiedenen Möglichkeiten zum Vergleichen von string funktionieren nicht unbedingt gleich.

Für diesen Beitrag haben gedankt: erfahrener Neuling
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Di 17.05.16 13:26 
Ok so kann man's auch machen, ist mir aber zu lang. Schade, dass es keine kürzere Variante gibt, aber man kann ja drauf warten.
Zitat:
Bei strings muß man sich immer fragen mit welchen Culture Einstellungen das gerade passiert
Ich momentan noch nicht (zum Glück) ;)
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 17.05.16 13:35 
Zitat:
Ok so kann man's auch machen, ist mir aber zu lang


Nun ja ich habs nur zu Ansichtszwecken inline gemacht. Wenn du das so wie von dir angegeben machen wolltest brauchst du ja eh eine Konstante Liste.
Da kann man dann auch wunderbar hingehen sich das string Array als Konstante vorzudefinieren und zur Seite legen. Wenn man dem dann noch einen schönen sprechenden Namen gibt hat man was wirklich lesbar.
Lesbarer als jede Aufzählung von strings in der if Abfrage je sein kann.
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Di 17.05.16 13:50 
Da hast du recht!
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 17.05.16 19:18 
Als kleine Rand-Info: Man kann die Array-Definition auch etwas kürzen. Die runten Klammern darum und der Typ können weg:

ausblenden C#-Quelltext
1:
if (new [] { "abc""123""xyz" }.Contains(myString))					


Wenn Du es ganz extrem willst, kannst Du dir ja auch mit einer Erweiterungsmethode behelfen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
public static class Extend_Object
{
    public static bool In<T>(this T source, params T[] items)
    {
        return items.Contains(source);
    }
    public static bool In<T>(this T source, IEqualityComparer<T> comparer, params T[] items)
    {
        return items.Contains(source, comparer);
    }
}
Und die Nutzung:
ausblenden C#-Quelltext
1:
if (myString.In("abc""123""xyz"))					

Für Strings kann dann ja noch eine Überladung hinzugefügt werden, welche die StringComparison bekommt.

Besser finde ich das aber nicht, sondern eher nach unnötigen Code.
Ich würde schon zu der Array-Variante von Ralf tendieren, aber das ist ja auch alles Geschmackssache.

Für diesen Beitrag haben gedankt: erfahrener Neuling
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Mi 18.05.16 13:51 
die gekürzte Array-Variante gefällt mir persöhlich am besten :zustimm:

Kann mir jemand erklären wo/wie bei der Klasse Extend_Object der Bezug zu einem string hergestellt wird? (Also das man mystring.In schreiben kann)
In ist ja ansich keine Methode der string-Klasse.
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Mi 18.05.16 14:41 
Das liegt daran, dass In<T> eine Extension Methode ist. Das Schlüsselwort dafür ist das this in der Parameterdefinition. Außerdem muss die entsprechende Methode statisch sein.
ausblenden C#-Quelltext
1:
2:
3:
4:
    public static bool In<T>(this T source, params T[] items)
    {
        return items.Contains(source);
    }


Die Version von Palladin007 ist generisch gehalten und kann daher z.B. auch für intlongdoubleobject oder einen anderen, beliebigen Typ verwendet werden.

Speziell für Strings würde die Methode so aussehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
    public static bool In(this string source, params string[] items)
    {
        return items.Contains(source);
    }

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler

Für diesen Beitrag haben gedankt: erfahrener Neuling
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 18.05.16 14:42 
Das Feature schimpft sich Extension Methods(Erweiterungsmethoden) (entscheidend ist das this am ersten Parameter)
Und 2.tens wird hier das implizite deduzieren des generischen Parameters gebraucht für die generischen in Methoden. Wenn string.In aufgerufen wird weiß der Compiler das für den generischen Typen T string zu nehmen ist.

Beispiel mit den Aufrufmöglichkeiten der Methode

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
static void Main(string[] args)
{
    string myString = "123";
    string[] myStrings = new[] { "abc""123""xyz" };
            
    Extend_Object.In<string>(myString, myStrings);  // expliziter Methodenaufruf 

    Extend_Object.In(myString, myStrings); // expliziter Methodenaufruf der generische Parameter T wird aus erstem Parameter deduziert. (T -> string) 

    myString.In<string>(myStrings); // Aufruf als Erweiterungsmethode

    myString.In(myStrings);  // Aufruf als Erweiterungsmethode generischer parameter T aus erstem Parameter (der jetzt Augrund des Erweiterungsmethoden Features jetzt links vom Punkt steht) deduziert.
}


Alle 4 Aufrufe erzeugen absolut identischen Laufzeitcode. Aber letzteres ist natürlich deutlich besser lesbar. Das ist reine Magie des Editors nichts was tief im Compiler versteckt wäre sondern nur den Aufrufsyntax vereinfacht.

Für diesen Beitrag haben gedankt: erfahrener Neuling
erfahrener Neuling Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 233
Erhaltene Danke: 19

Win 7, Win 10
C#, ASP-MVC (VS 2017 Community), MS SQL, Firebird SQL
BeitragVerfasst: Mi 18.05.16 15:06 
coole Sache :)
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 18.05.16 18:51 
Als kleine Ergänzung:

Die Klasse, in der die Extension-Method ist, muss ebenfalls statisch sein.



Besonders hilfreich ist sowas bei Typen, die nicht mehr erweitert werden können, also vorhandene Typen, wo der Source-Code nicht vorliegt oder Typen, die keine eigene Funktionalität enthalten können, wie z.B. Enums oder Interfaces.
Außerdem nutze ich das ganz gerne für Überladungen von Methoden. Ich setze dann in der eigentlichen Klasse eine "Haupt"-Methode um und dazu schreibe ich noch ein paar Erweiterungs-Methoden, die den Aufruf der "Haupt"-Methode vereinfachen. So reduziere ich den Code in der Klasse auf das wesentliche für die Klasse Notwendige, während alle Vereinfachungen in einer eigenen Klasse liegen.

Als kleiner Tipp: Klassen mit Extension-Methods sollten (mMn) immer möglichst weit "oben" im Namespace liegen, denn theoretisch kannst Du ein Objekt von einem Typen irgendwie bekommen, ohne ein using für das Namespace zu haben. Du brauchst aber dieses Namespace um die Extension-Method zu finden. Um das zu umgehen, lege ich Klassen mit ExtensionMethods möglichst weit oben im Namespace an.
Außerdem habe ich mich für die Namen für das Format "Extend_NameDesTyps" entschieden. Den Klassen-Namen selber nutze ich nie direkt, so lässt sich die Klasse aber leicht von Anderen unterscheiden.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 18.05.16 19:06 
Zitat:
Außerdem habe ich mich für die Namen für das Format "Extend_NameDesTyps" entschieden.


Bei einem generischen Typen schwer durchzuhalten ;)
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 18.05.16 19:26 
Bei generischen Typen denke ich mir den generischen Typ-Parameter immer weg ^^

Wenn ich z.B. zwei Klassen mit dem selben Namen habe, eine davon aber generisch, dann lege ich die auch in die selbe Datei. ZUmindest solange die Datei nicht zu groß wird :D
Und genauso mache ich das auch bei ExtensionMethods ^^