Frage

Ich habe eine Adresse Objekt, das Eigenschaften AddressLine1, AddressLine2 hat, Vorort, Staat, ZipCode. (Es gibt mehr, aber das ist genug für das Beispiel). Auch jede dieser Eigenschaften sind Strings. Und ich bin mit C # 3.0.

Ich will es als String darstellen, sondern als ich tue, dass ich finde, dass ich eine Methode mit einer hohen zyklomatische Komplexität bin zu schaffen wegen der vielen if-Anweisungen ...

die Zeichenfolge zu jeder Eigenschaft zugeordnet Unter der Annahme, der gleiche wie der Name der Eigenschaft (dh AddressLine1 = „AddressLine1“) ... Ich möchte die Adresse dargestellt werden, wie folgt:

"AddressLine1 AddressLine2 Vorort Staat ZipCode".

Nun hatte die ursprüngliche Art, wie ich dies getan, durch eine einfache String.Format ist ()

String.Format("{0} {1} {2} {3} {4}", address.AddressLine1, 
address.AddressLine2, address.Suburb, address.State, address.ZipCode);

Das ist alles schön und gut, bis ich, dass einige dieser Felder gefunden haben, kann leer sein ... insbesondere AddressLine2. Das Ergebnis ist ein zusätzliche nicht benötigte Räume ... das sind besonders ärgerlich, wenn Sie in einer Reihe mehr erhalten.

Um dieses Problem zu bekommen, und die einzige Lösung, die ich denken kann, habe ich die Zeichenfolge manuell hatte zu bauen und nur die Adresseigenschaften auf die Zeichenfolge hinzufügen, wenn sie nicht null oder leer sind.

dh

string addressAsString = String.Empty;

if (!String.IsNullOrEmpty(address.AddressLine1))
{
    addressAsString += String.Format("{0}", address.AddressLine1);
}

if(!String.IsNullOrEmpty(address.AddressLine2))
{
    addressAsString += String.Format(" {0}", address.AddressLine2);
}

etc....

Gibt es eine elegantere und / oder prägnante Art und Weise, dies zu erreichen, dass ich nicht darüber nachdenken? Meine Lösung nur fühlt chaotisch und aufgebläht ... aber ich kann einen besseren Weg nicht denken, es zu tun ...

Für alles, was ich weiß, das ist meine einzige Option gegeben, was ich tun will ... aber ich dachte, ich würde diese dort werfen, um zu sehen, ob jemand mit mehr Erfahrung als ich einen besseren Weg kennt. Wenn Theres keine bessere Option dann naja ... aber wenn ja, dann werde ich etwas lernen ich vorher nicht kannte.

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Dies möglicherweise nicht die effizienteste Art und Weise, aber es ist prägnant. Sie könnten die Elemente setzen Sie in ein Array wollen und diejenigen ohne einen signifikanten Wert herauszufiltern, so dass sie dann verbinden.

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var addr = string.Join(" ", values.ToArray());

Wahrscheinlich effizienter, aber etwas schwieriger zu lesen, wäre es, die Werte in eine StringBuilder zu aggregieren, z.

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var builder = new StringBuilder(128);
values.Aggregate(builder, (b, s) => b.Append(s).Append(" "));
var addr = builder.ToString(0, builder.Length - 1);

ich wahrscheinlich zu so etwas wie die ersten Implementierung anlehnen würde, da es viel einfacher und wartbaren Code ist, und dann, wenn die Leistung ein Problem etwas mehr wie die zweiten betrachten ist (wenn es schneller sein muss entpuppen ... ).

(Beachten Sie diese C # 3.0 erfordert, aber Sie nicht Ihre Sprachversion erwähnen, so dass ich davon aus, das OK ist).

Andere Tipps

Wenn Strings zusammen setzen empfehle ich Ihnen die Stringbuilder-Klasse verwenden. Grund dafür ist, dass ein System.String unveränderlich ist, so dass jede Änderung, die Sie in einen String machen einfach gibt einen neuen String.

Wenn Sie ein Objekt in Text darstellen wollen, könnte es eine gute Idee, den ToString () -Methode außer Kraft zu setzen und Ihre Implementierung in dort zu setzen.

Last but not least, mit Linq in C # 3.5 du gerade getan hast hier diejenigen zusammen wie Greg Beech beitreten können, aber statt mit string.Join () verwenden:

StringBuilder sb = new StringBuilder();
foreach (var item in values) {
  sb.Append(item);
  sb.Append(" ");
}

Hope, das hilft.

Ich würde empfehlen, die ToString-Methode überschreiben, und nehmen Sie eine IFormatProvider-Implementierung, die Ihre benutzerdefinierte Typen definiert.

Siehe MSDN unter http://msdn.microsoft.com/ en-us / library / system.iformatprovider.aspx für Informationen zur Implementierung IFormatProvider.

Sie könnten dann Code wie folgt aus:
address.ToString ( "s"); // Kurzadresse
address.ToString ( "was auch immer"); // was benutzerdefiniertes Format, das Sie definieren.

Auf jeden Fall nicht der einfachste Weg, es zu tun, aber das sauberste IMHO. Ein Beispiel einer solchen Umsetzung ist die Datetime-Klasse.

Prost
Ash

Erstens erfordert eine Adresse bestimmte Informationen, so sollten Sie keine Adresse erlauben, die nicht, sagen wir, ein Zip-Code hat. Sie können auch sicherstellen, dass sie niemals null sind durch jede Eigenschaft auf eine leere Zeichenfolge initialisieren, oder durch jede Eigenschaft als Argumente an den Konstruktor erfordert. Auf diese Weise wissen Sie, dass Sie mit gültigen Daten handeln bereits, so können Sie eine formatierte Zeichenfolge ohne die Notwendigkeit für die IsNullOrEmpty prüft gerade ausgegeben.

Ich hatte ein ähnliches Problem eine mehrzeilige Kontakt Zusammenfassung Aufbau, die möglicherweise mehrere leere Felder gehabt haben könnte. Ich habe so ziemlich das gleiche, was Sie taten, außer ich einen String-Builder verwendet als nicht über einen String verketten zu halten und immer wieder.

Wenn Sie Ihre Daten nicht absolut zuverlässig ist, werden Sie diese Logik irgendwo haben müssen - ich würde vorschlagen, dass Sie eine andere schreibgeschützt erstellen Eigenschaft (nennen wir es so etwas wie FormattedAddress), der diese Logik für Sie tut. Auf diese Weise müssen Sie sich nicht von dem Code ändern Sie es, irgendwann Sie aufzuräumen oder auf andere Weise die Regeln ändern.

Und +1 für den Vorschlag, einen Stringbuilder zu verwenden, wie zum Verketten von Strings gegenüber.

Ich weiß, das wirklich alt ist, aber ich spürte eine allgemeine Lösung und Mine auf diese Weise umgesetzt:

private static string GetFormattedAddress(
    string address1,
    string address2,
    string city,
    string state,
    string zip)
{
    var addressItems =
        new []
        {
            new[] { address1, "\n" },
            new[] { address2, "\n" },
            new[] { city, ", " },
            new[] { state, " " },
            new[] { zip, null }
        };

    string suffix = null;
    var sb = new StringBuilder(128);

    foreach (var item in addressItems)
    {
        if (!string.IsNullOrWhiteSpace(item[0]))
        {
            // Append the last item's suffix
            sb.Append(suffix);

            // Append the address component
            sb.Append(item[0]);

            // Cache the suffix
            suffix = item[1];
        }
    }

    return sb.ToString();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top