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":
- Eine Instanzvariable anlegen und bei jedem foreach Durchlauf jeweils den key darin verfrachten
- 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: