Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Was mich an VB.NET stoert oder was an C# toll ist

Vorneweg: Primär arbeite ich im Geschäft mit VB.NET, Privat aber praktisch nur mit C#.

Letztens hatte ich eine relativ einfach Aufgabe.
Es bestand eine gefüllte NameValueCollection und ein String mit einer oder mehreren Ausnahme(n).
Die Aufgabe bestand nun darin, die NameValueCollection in einen verketten String zu verfrachten, ausser alle Schlüssel die in den Ausnahmen standen und der Vergleich soll case-insensitiv (Gross- Kleinschreibung egal) ablaufen.

Schritt 1:
String per String.Split() anhand eines Trennzeichens trennen -> Resultat ist ein String Array

Schritt 2:
Die Collection Paar für Paar duchzugehen und dabei gegen die Ausnahmen die im String Array stehen, nicht zum Resultat hinzuzufügen

Hört sich einfach und intuitiv lösbar an?
Ist es aber nicht, zumindest nicht in VB.NET.

Okay, ich mag unter Einfachheit und Intuitivität etwas anderes vorstellen als manch anderer.
Sobald ich einen Umweg über eine zusätzliche Liste oä. machen muss, ist es in meinen Augen nicht mehr einfach und intuitiv.

Natürlich ist es einfach zu lösen, aber der Code bläht sich auf, etc...

Die Klasse "Array" hat eine passende Methode ".Exists" dachte ich mir. Da kann ja nichts schiefgehen.
Nun, diese Methode erwartet im ersten Parameter den Array (Ich gehe von der Array Klasse und deren statischen Methode Exists aus), und als zweiten Parameter ein Predicate.

(Für alle Besserwisser, ich weiss das es <Array>.IndexOf() gibt, jedoch gibt es da keine Möglichkeit zu einer case-insensitiven Abfrage.)

In VB.NET gibt es leider keine Anonymen Methoden, wie das in C# der Fall ist.
Also bleibt nur den Weg über eine weitere Methode, was auch nicht weiter schlimm ist.

Jedoch steht dann in dieser Methode nur aktuelle Suchstring zur Verfügung, gegen den verglichen werden kann.
Meine lokale Variable "key" - also der aktuelle Schlüssel meiner Collection, gegen den ich vergleichen möchte, ist nicht in der Predicate Methode zugänglich.

Wege zum "Glück":

  1. Eine Instanzvariable anlegen und bei jedem foreach Durchlauf jeweils den key darin verfrachten
  2. Die Predicate Methode in eine Klasse verfrachten, dieser eine Instanzvariable spendieren und im Konstruktor füllen

Das kanns doch nicht wirklich sein, so eine Zangengeburt möchte ich echt nicht.
VB.NET ist ansonsten, ganz angenehm, obwohl ich lieber mit C# arbeite. (Nur um auch gute Worte einzulegen :)

In der VB.NET Lösung habe ich den Workaround gewählt, bei jedem foreach Durchlauf jeweils durch den Ausnahmearray zu iterieren und zu vergleichen.

Die C# Lösung kann mit anonymen Methoden so schön und einfach aussehen:

foreach(string key in queryColl) {
    if(!Array.Exists<string>(exceptionsArray,
                    delegate(string search) {
                        return search.Equals(key, StringComparison.OrdinalIgnoreCase);
                    }))
        returnValue += "&" + key + "=" + queryColl[key];
}

Feedback: VB.NET Variante von Stefan Falz

Dim Result As String = String.Empty
Dim ExclusionArray As New Collections.Generic.List( Of String )
   ExclusionArray.AddRange( "hTtp_uSEr_AgEnt,HTTPS_KEYSIZE,remote_addr".ToLower().Split( "," ) )
   For Each Value As String In Request.ServerVariables
       If Not ExclusionArray.Contains( Value.ToLower() ) Then
           Result &= Value & "<br />"
       End if
   Next
    [...]

Sieht gut aus, an diese Möglichkeit habe ich nicht gedacht, den Array so elegant in eine Liste zu packen.
Trotzdem ist es dann ein Array _und_ eine Liste. Aber hier siehts keiner ;-)

Noch mehr Feedback: VB.NET (Framework 3.5) Variante von Daniel Walzenbach (MS)

Dieses Beispiel benutzt Features von .NET 3.5, siehe Lambdas und LINQ.

Dim result As String = String.Empty
Dim sentence = "the Quick brOwn fox JUMPS over thE Lazy dog".Split(New Char() {CChar(" ")}, StringSplitOptions.RemoveEmptyEntries)
Dim exceptionsArray = "the jumps".Split(New Char() {CChar(" ")}, StringSplitOptions.RemoveEmptyEntries)


Dim query = (From item In sentence _
              Select item).Except((From except In exceptionsArray), _
                                      StringComparer.OrdinalIgnoreCase)

For Each item In query
    result &= item & "<br />"
Next

Mehr Informationen über Predicates, Anonyme Methoden und Array.Exists (generisch) findet ihr unter folgenden Links:

Veröffentlicht Mittwoch, 19. Dezember 2007 19:42 von Peter Bucher
Abgelegt unter: , , , ,

Kommentare

Keine Kommentare
Anonyme Kommentare sind nicht zugelassen