将地址对象转换为字符串的最佳方式是什么?

问题描述:

我有一个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.... 

是否有一个更优雅和/或简明的方式来实现这一目标,我不是在想什么?我的解决方案只是感觉凌乱和臃肿...但我想不出一个更好的方式来做到这一点...

对于我所知道的,这是我唯一的选择给予我想要做的..但我只是认为我会把它放在那里,看看比我更有经验的人是否知道更好的方法。如果没有更好的选择,那么哦...但如果有的话,那么我会去学习一些我以前不知道的东西。

在此先感谢!

这可能不是最有效的方式,但它很简洁。你可以把你想要的项目放到一个数组中,并过滤掉没有重要值的项目,然后加入它们。

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

首先,地址需要一定的信息,所以你不应该允许一个地址没有,比如说一个邮政编码。通过将每个属性初始化为空字符串,或者通过要求每个属性作为构造函数的参数,您还可以确保它们从不为空。这样你就知道你已经处理了有效的数据,所以你可以输出一个格式化的字符串,而不需要IsNullOrEmpty检查。

我有一个类似的问题,建立一个可能有多个空字段的多行联系人摘要。我几乎做了同样的事情,除了我使用了一个字符串生成器来保持连续不断的连接字符串。

+0

我曾考虑过StringBuilder ......但不幸的是,唯一一次使用StringBuilder具有任何性能优势的是,当您有一个循环循环10次或更多次时... – mezoid 2009-03-02 01:26:36

如果你的数据不是完全可靠的,你需要将该逻辑放在某个地方 - 我建议你创建另一个只读属性(称之为FormattedAddress),它为你执行逻辑。这样,您不必更改任何代码,在某些时候,您可以清理或更改规则。

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

将字符串放在一起时,我建议您使用StringBuilder类。原因是System.String是不可变的,所以每次对字符串进行的更改都会返回一个新的字符串。

如果你想用文本表示一个对象,重写ToString()方法并把你的实现放在那里可能是一个好主意。

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

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

希望这有助于。

我会建议覆盖ToString方法,并采取定义您的自定义类型的IFormatProvider实现。

有关实施IFormatProvider的信息,请参阅MSDN http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

然后你可以这样编码:
address.ToString(“s”); //短地址
address.ToString(“whatever”); //您定义的任何自定义格式。

绝对不是最简单的方法,但最干净的恕我直言。这种实现的一个例子是DateTime类。

干杯