c# - 添加列表使用反射的属性
问题描述
我正在阅读一个类似的文件
高动态范围……</p>
林……</p>
林……</p>
林……</p>
高动态范围……</p>
林……</p>
林……</p>
现在 LIN 对应行项目,属于它上面的 HDR 行。
此外,数据的映射来自已经反序列化的 xml。这具有映射,例如在 Header 或 LineItems 类中存储数据的属性、要选择的字符数、是否需要等。
存储数据的标头模型看起来像
public class Header
{
public string Id { get; set; }
public string Description { get; set; }
public List<Item> LineItems { get; set; }
}
我正在尝试使用通用函数在处理数据之前加载数据。
我需要帮助
- (#1) 在下面的函数中:在将 LineItem 添加到之前确保属性 LineItems 不为空的正确方法是什么?
- 如何在下面的函数中执行(#2),使用反射将 lineItem 添加到
data[headindex-1].LineItems.Add(lineItem)
?
这里是函数...
public static List<H> ReadFile<H, I>(ConfigTypeUploadXml uploadConfig, string fileNamePath, ref string errMsg) where H : new() where I : new()
{
// we'll use reflections to add LineItems to data
var properties = typeof(H).GetProperties();
// read the file line by line and add to data.
var data = new List<H>();
var headIndex = 0;
var lineIndex = 1;
foreach (var line in File.ReadAllLines(fileNamePath))
{
// read HDR line
if (line.StartsWith("HDR"))
{
var header = ReadHeaderLine<H>(uploadConfig, line, errMsg);
data.Add(header);
headIndex += 1;
}
// read LIN line
if (line.StartsWith("LIN"))
{
var lineItem = ReadItemLine<I>(uploadConfig, line, errMsg);
foreach (var p in properties)
{
if (p.Name != "LineItems")
continue;
//1) if items is null then create the object
object items = p.GetValue(data[headIndex - 1], null);
if (items == null)
p.SetValue(data[headIndex - 1], new List<I>());
//2) add line item to data[headIndex - 1].LineItems.Add(lineItem)
}
}
lineIndex += 1;
}
return data;
}
这篇文章使用反射将项目添加到 List<T>展示了如何做到这一点,但这在主要对象上。就我而言,我需要填充data[index].LineItems.Add(...)
解决方案
这需要通过反射来完成吗?您可以创建一个所有类似Header
类都实现的简单接口,例如
interface IHaveLineItems
{
void AddLineItem(object item);
}
这可以在各种Header
类上实现,例如
public class Header : IHaveLineItems
{
public string Id { get; set; }
public string Description { get; set; }
public List<Item> LineItems { get; set; }
void IHaveLineItems.AddLineItem(object item)
{
LineItems.Add((Item)item);
}
}
你的循环可能会变成:
var data = new List<H>();
IHaveLineItems lastHeader = null;
var lineIndex = 1;
foreach (string line in File.ReadAllLines(fileNamePath))
{
// read HDR line
if (line.StartsWith("HDR"))
{
var header = ReadHeaderLine<H>(uploadConfig, line, errMsg);
data.Add(header);
lastHeader = header;
}
// read LIN line
if (line.StartsWith("LIN"))
{
var lineItem = ReadItemLine<I>(uploadConfig, line, errMsg);
lastHeader.AddLineItem(lineItem);
}
lineIndex += 1;
}
推荐阅读
- swift - 由于处理程序而调用了两次函数,如何修复它以便只调用一次?
- sql - 为什么这个 SQL 查询有效,而另一个却没有?
- c - 在单行代码中对单个变量进行多次赋值
- r - 如何查找和绘制多个短语的频率总计?
- python-3.x - 有没有办法通过 youtube API 上的 viewCount 来搜索视频?
- specifications - 如何在 dafny 中编写将 char 数组转换为整数的方法的规范?
- postgresql - 为 ASP.NET Core 5.0 - EF Core 5.0 Web App 配置 PostgreSQL 连接字符串以在 MS 或 Linux 云上运行?
- python - 如何在 Python 中正确编写 .onclick()?
- sqlite - 如何 Brew 安装 SQLite3 FTS5 扩展?
- reactjs - React 中的类组件中的这个对象?