我正在使用网络服务向我返回JsonAddressModel
,以换取我在不同地方申请中的string
。
我需要在表单的确认页面上将客户地址打印为连续的string
。
我最初编写了这个方法,它的目的是用逗号分隔每个属性并省略任何null属性,但这种方法效果很好但是肯定是非常重复的。
原创方法
public static string ConcatAddress(JsonAddressModel jsonAddressModel)
{
StringBuilder builder = new StringBuilder();
if (jsonAddressModel.saon.Replace(" ", "") != "" && jsonAddressModel != null)
builder.Append(jsonAddressModel.saon + ", ");
if (jsonAddressModel.paon != null)
builder.Append(jsonAddressModel.paon + ", ");
if (jsonAddressModel.thorofare != null)
builder.Append(jsonAddressModel.thorofare + ", ");
if (jsonAddressModel.dthorofare != null)
builder.Append(jsonAddressModel.dthorofare + ", ");
if (jsonAddressModel.posttown != null)
builder.Append(jsonAddressModel.posttown + ", ");
if (jsonAddressModel.county != null)
builder.Append(jsonAddressModel.county + ", ");
if (jsonAddressModel.postcode != null)
builder.Append(jsonAddressModel.postcode);
return builder.ToString();
}
经过测试后,我试图以更优雅的方式进行重构,并决定尝试使用反射来计算JsonAddressModel
的属性,并使用foreach
循环依次附加每个属性
新方法
public static string ConcatAddress(JsonAddressModel jsonAddressModel)
{
StringBuilder builder = new StringBuilder();
foreach (PropertyInfo prop in jsonAddressModel.GetType().GetProperties())
{
if (prop != null)
{
builder.Append(prop.GetValue(jsonAddressModel, null) + ",");
}
}
return builder.ToString();
}
问题
虽然新方法现在附加了我想要显示的每个正确属性,例如saon / paon,thorofare等。它还附加了eastings,northings,uprn以及System.Runtime.Serialization.ExtensionDataObject
之类的东西。显然我不希望在我的连接地址字符串中包含这些内容。
问题
有没有确切规定我允许在这里附加哪些属性?
我认为BindingFlags
在我的实例中不起作用,因为如前所述,我从Web服务接收此模型,并且我想要和不想要的属性分别是{{1} }。
我考虑过创建一个数组但是我能看到的唯一名称相关字段是Private
,它类似于SetMethod
但是对于每个属性,我不完全确定如何抓住这个。
答案 0 :(得分:2)
有可能通过反思做出你所要求的事情,但是你并没有提供任何关于你想要的项目之间差异的信息。包括和那些你没有。
但是,在这种情况下,您可以在保留重要部分(即确定哪些项目包含在输出中的部分)的同时消除代码中的重复,并且作为奖励,它会更有效率而不是使用反射。
public static string ConcatAddress(JsonAddressModel jsonAddressModel)
{
var nonEmptyProperties = new [] {
jsonAddressModel.saon,
jsonAddressModel.paon,
jsonAddressModel.thorofare,
jsonAddressModel.dthorofare,
jsonAddressModel.posttown,
jsonAddressModel.county,
jsonAddressModel.postcode,
}.Where(s => !string.IsNullOrWhiteSpace(s));
return string.Join(", ", nonEmptyProperties);
}
答案 1 :(得分:2)
这是一个更通用的方法,您可以在函数调用中指定参数:
public string ConcatProperties<T>(T input, params Func<T, string>[] propertyDelegates)
{
return string.Join(
",",
propertyDelegates
.Select(p => p(input))
.Where(s => !string.IsNullOrEmpty(s));
}
你这样使用它:
var concatenatedString = ConcatProperties(thingy,
x => x.Foo,
x => x.Bar,
x => x.Wobble);
注意:这仅适用于字符串属性,对于您需要将属性转换为字符串的其他属性(例如x => x.Wibble.ToString()
)
答案 2 :(得分:0)
是的,Linq非常容易:
而不是直接使用
foreach (PropertyInfo prop in jsonAddressModel.GetType().GetProperties())
{
// ...
}
你可以使用
var desiredProperties = new List<string>
{
"saon",
"paon"
};
IEnumerable<PropertyInfo> pis = jsonAddressModel.GetType().GetProperties();
var filteredPropertyInfos = pis.Where(pi => desiredProperties.Contains(pi.Name));
foreach (PropertyInfo prop in filteredPropertyInfos)
{
// ...
}