c# - 仅在有值时才获取属性名称和值
问题描述
我正在尝试模拟一个 .csv 文件,其中属性名称列表作为标题行,后跟项目列表的实际属性列表。
目前,我让它工作,但现在只需要包含属性的标题和值,其中项目在 list 中的任何位置都有该属性的值。
这是我目前拥有的:
public static string LeadsToCSVString(List<Lead> leads)
{
StringBuilder builder = new StringBuilder();
PropertyInfo[] properties = typeof(Lead).GetProperties();
builder.AppendLine(string.Join(",", properties.Select(x => x.Name)));
foreach (Lead lead in leads)
{
builder.AppendLine(string.Join(",", properties.Select(x => x.GetValue(lead))));
}
return builder.ToString();
}
在哪里Lead
:
public class Lead
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsOk { get; set; }
}
不能保证所有属性值都具有值,List<Lead>
甚至可能存在以下属性没有值的情况:
FirstName,LastName,IsOK
Joe,,false
Adam,,true
需要做的是只有属性具有实际值的标题值和行列值。如果我采用上面的示例列表,CSV 字符串将如下所示:
FirstName,IsOk
Joe,false
Adam,true
我怎样才能修改我的代码来做到这一点?
如果列表中的任何对象具有该属性的值,会发生什么情况的一些示例:
FirstName,LastName,IsOK
Joe,Dirt,
Adam,,true
FirstName,LastName,IsOK
,Dirt,
Adam,,true
解决方案
假设“有一个值”意味着它的值不为空(仅适用于引用类型和 Nullable 值类型),您可以过滤掉列表中没有任何值的那些:
var filteredProps = properties.Where(p => leads.Any(l => p.GetValue(l) != null));
..然后使用filteredProps
而不是properties
:
public static string LeadsToCSVString(List<Lead> leads)
{
StringBuilder builder = new StringBuilder();
PropertyInfo[] properties = typeof(Lead).GetProperties();
var filteredProps = properties.Where(p => leads.Any(l => p.GetValue(l) != null));
builder.AppendLine(string.Join(",", filteredProps.Select(x => x.Name)));
foreach (Lead lead in leads)
{
builder.AppendLine(string.Join(",", filteredProps.Select(x => x.GetValue(lead))));
}
return builder.ToString();
}
或者为了避免调用GetValue()
两次,您可以创建属性及其值的字典(或查找):
public static string LeadsToCSVString(List<Lead> leads)
{
StringBuilder builder = new StringBuilder();
PropertyInfo[] properties = typeof(Lead).GetProperties();
var propsDictionary =
properties.ToDictionary(p => p, p => leads.Select(l => p.GetValue(l)).ToArray())
.Where(pair => pair.Value.Any(o => o != null))
.ToDictionary(pair => pair.Key, pair => pair.Value);
builder.AppendLine(string.Join(",", propsDictionary.Keys.Select(x => x.Name)));
foreach (Lead lead in leads)
{
builder.AppendLine(
string.Join(",", propsDictionary.Keys.Select(x => x.GetValue(lead))));
}
return builder.ToString();
}
推荐阅读
- azure - 在 IISExpress 与 Service Fabric 群集上托管时 I/O 流量行为的差异。为什么?
- c# - 允许在可浏览属性的组合框中复制/粘贴
- css - R shinydashboardPlus 2.0.0 相当于 sidebar_fullCollapse(或 css)
- iis - ASP.net MVC 站点无法在 Windows Server 2019 上运行
- javascript - 如何使用 React hook 修复渲染的钩子比上一次渲染时更多的钩子
- firebase - Firebase 云消息传递对于在 Web 应用程序中开发聊天系统是否可靠?
- performance - Julia - 加快字符串到日期或日期时间的转换
- html - 图像位置推出元素
- html - 内联文本居中对齐
- algorithm - 求解斐波那契数列的非齐次递归关系