将地址对象转换为字符串的最佳方式是什么?
我有一个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,但你没有提到你的语言版本,所以我假设这是好的)。
首先,地址需要一定的信息,所以你不应该允许一个地址没有,比如说一个邮政编码。通过将每个属性初始化为空字符串,或者通过要求每个属性作为构造函数的参数,您还可以确保它们从不为空。这样你就知道你已经处理了有效的数据,所以你可以输出一个格式化的字符串,而不需要IsNullOrEmpty检查。
我有一个类似的问题,建立一个可能有多个空字段的多行联系人摘要。我几乎做了同样的事情,除了我使用了一个字符串生成器来保持连续不断的连接字符串。
我曾考虑过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类。
干杯
灰
,看起来像一个有趣的解决方案...我会尝试一下,看看它是如何去... – mezoid 2009-03-02 01:27:16
烨... C#3.0是我使用的是什么.. 。我会更新标签,以反映... – mezoid 2009-03-02 01:28:00
真棒解决方案格雷格!感谢堆!它将20多行减少到3个易于理解的易于理解的行。我真的需要在Linq开始思考。 – mezoid 2009-03-02 01:45:35