C#LINQ三元运算符作为foreach中的switchcase

use*_*636 2 c# linq ternary-operator switch-statement

我正在使用LINQ和HtmlAgilitypack从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));
Run Code Online (Sandbox Code Playgroud)

到目前为止它的工作完美,除了我需要一些定制.

  1. 选择要添加的列.
  2. 并指定列类型.

这个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
            }
Run Code Online (Sandbox Code Playgroud)

但是我对LINQ和C#真的很新,我想在第一个片段中的foreach中实现上面的开关案例,我知道我应该使用ternary operator,但我不确定sytax.

Ree*_*sey 5

我将开关包装到一个方法中,然后从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);
Run Code Online (Sandbox Code Playgroud)

请注意,没有必要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));
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将您的方法编写为:

void AddColumnToDataTable(string columnName, DataTable table)
{
    table.Columns.Add(columnName, typeLookup[columnName]);
}
Run Code Online (Sandbox Code Playgroud)