2009-03-02 107 views
1

我有一個Address屬性AddressLine1,AddressLine2,Suburb,State,ZipCode。 (還有更多,但這個例子足夠了)。此外,每個屬性都是字符串。我正在使用C#3.0。將地址對象轉換爲字符串的最佳方式是什麼?

我想它表示爲一個字符串,但我做了我發現,我創建具有高圈複雜度的方法,由於所有的if語句...

假設分配給每個屬性的字符串與屬性的名稱相同(即AddressLine1 =「AddressLine1」)...我希望地址如下所示:

「AddressLine1 AddressLine2 Suburb State ZipCode」。現在

,原有的方式,我做了,這是通過簡單的String.Format()

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

這是一個好主意,直​​到我發現了一些這些字段可以是空..特別是AddressLine2。其結果是額外的不必要的空間......當你連續得到幾個時,這些空間特別惱人。

爲了解決這個問題,以及我能想到的唯一解決方案,我必須手動構建字符串,並且只將地址屬性添加到字符串(如果它們不爲null或爲空)。

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.... 

是否有一個更優雅和/或簡明的方式來實現這一目標,我不是在想什麼?我的解決方案只是感覺凌亂和臃腫...但我想不出一個更好的方式來做到這一點...

對於我所知道的,這是我唯一的選擇給予我想要做的..但我只是認爲我會把它放在那裏,看看比我更有經驗的人是否知道更好的方法。如果沒有更好的選擇,那麼哦...但如果有的話,那麼我會去學習一些我以前不知道的東西。

在此先感謝!

回答

2

這可能不是最有效的方式,但它很簡潔。你可以把你想要的項目放到一個數組中,並過濾掉沒有重要值的項目,然後加入它們。

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

可能更有效,但稍微更難閱讀,將這些值聚集成一個StringBuilder,例如

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); 

我對像第一個實現大概瘦,因爲它是更簡單,更易於維護的代碼,然後如果性能是一個問題,考慮更多的東西一樣,第二個(如果它變成是更快...)。

(注意這需要C#3。0,但你沒有提到你的語言版本,所以我假設這是好的)。

+0

,看起來像一個有趣的解決方案...我會嘗試一下,看看它是如何去... – mezoid 2009-03-02 01:27:16

+0

燁... C#3.0是我使用的是什麼.. 。我會更新標籤,以反映... – mezoid 2009-03-02 01:28:00

+0

真棒解決方案格雷格!感謝堆!它將20多行減少到3個易於理解的易於理解的行。我真的需要在Linq開始思考。 – mezoid 2009-03-02 01:45:35

0

首先,地址需要一定的信息,所以你不應該允許一個地址沒有,比如說一個郵政編碼。通過將每個屬性初始化爲空字符串,或者通過要求每個屬性作爲構造函數的參數,您還可以確保它們從不爲空。這樣你就知道你已經處理了有效的數據,所以你可以輸出一個格式化的字符串,而不需要IsNullOrEmpty檢查。

0

我有一個類似的問題,建立一個可能有多個空字段的多行聯繫人摘要。我幾乎做了同樣的事情,除了我使用了一個字符串生成器來保持連續不斷的連接字符串。

+0

我曾考慮過StringBuilder ......但不幸的是,唯一一次使用StringBuilder具有任何性能優勢的是,當您有一個循環循環10次或更多次時... – mezoid 2009-03-02 01:26:36

0

如果你的數據不是完全可靠的,你需要將該邏輯放在某個地方 - 我建議你創建另一個只讀屬性(稱之爲FormattedAddress),它爲你執行邏輯。這樣,您不必更改任何代碼,在某些時候,您可以清理或更改規則。

和+1建議使用stringbuilder,而不是連接字符串。

1

將字符串放在一起時,我建議您使用StringBuilder類。原因是System.String是不可變的,所以每次對字符串進行的更改都會返回一個新的字符串。

如果你想用文本表示一個對象,重寫ToString()方法並把你的實現放在那裏可能是一個好主意。

最後但並非最不重要的,使用LINQ在C#3.5,你可以加入那些在一起像格雷格山毛櫸只是在這裏做的,但不是使用的string.join()使用方法:

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

希望這有助於。

1

我會建議覆蓋ToString方法,並採取定義您的自定義類型的IFormatProvider實現。

有關實施IFormatProvider的信息,請參閱MSDN http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

然後你可以這樣編碼:
address.ToString(「s」); //短地址
address.ToString(「whatever」); //您定義的任何自定義格式。

絕對不是最簡單的方法,但最乾淨的恕我直言。這種實現的一個例子是DateTime類。

乾杯

相關問題