c# LINQ三元操作符作为foreach中的开关箱
本文关键字:foreach 开关箱 操作符 三元 LINQ | 更新日期: 2023-09-27 18:02:39
我正在使用LINQ和htmllagilitypack来创建一个HTML的数据表。下面的代码获取HTML表头并构造数据表列:
var nodes = htmlDoc.DocumentNode.SelectNodes("//table[@class='ps-sellers-table crts']/tr");
nodes[0].Elements("th")
.Skip(0)
.Select(th => th.InnerText
.Trim())
.ToList()
.ForEach(header => dt.Columns.Add(header));
到目前为止,它工作得很好,除了我需要一些定制。
- 选择要添加的列
- 并指定列类型。
这个select语句将做上面的两件事:
switch (header)
{
case ("id") : dt.Columns.Add(header,typeof(int)); break;
case ("name") : dt.Columns.Add(header,typeof(string)); break;
case ("price") : dt.Columns.Add(header,typeof(decimal)); break;
case ("shipping") : dt.Columns.Add(header,typeof(decimal)); break;
default : //skip the column and dont add it
}
然而,我是LINQ和c#的新手,我想在第一个代码片段中的foreach内部实现上述开关情况,我知道我应该使用ternary operator
,但我不确定语法。
我会将switch封装到一个方法中,然后在select语句中调用该方法。
我的版本看起来像:
var nodes = htmlDoc.DocumentNode.SelectNodes("//table[@class='ps-sellers-table crts']/tr");
nodes[0].Elements("th")
.Select(th => th.InnerText.Trim());
foreach(var node in nodes)
AddColumnToDataTable(node, dt);
注意,不需要Skip(0)
,调用ToList()
只是为了使用List<T>.ForEach
会降低可读性并增加开销。我个人更喜欢使用普通的foreach
。
话虽如此,您的方法可以重构为使用Dictionary<string, Type>
代替。如果你把这个添加到你的类中:
Dictionary<string, Type> typeLookup;
// In your constructor:
public YourClass()
{
typeLookup.Add("id", typeof(int));
typeLookup.Add("name", typeof(string));
typeLookup.Add("price", typeof(decimal));
typeLookup.Add("shipping", typeof(decimal));
}
你可以这样写你的方法:
void AddColumnToDataTable(string columnName, DataTable table)
{
table.Columns.Add(columnName, typeLookup[columnName]);
}
您可以直接将switch添加到foreach中,但不确定为什么必须使用三元操作符
.ToList().ForEach(header =>
{
switch (header)
{
case ("id"): dt.Columns.Add(header, typeof(int)); break;
case ("name"): dt.Columns.Add(header, typeof(string)); break;
case ("price"): dt.Columns.Add(header, typeof(decimal)); break;
case ("shipping"): dt.Columns.Add(header, typeof(decimal)); break;
default: break; //skip the column and dont add it
}
});