我的lambda表达式出了什么问题

时间:2011-03-16 05:06:49

标签: c# asp.net lambda

我想获取一系列checkedListbox选择的值,如1,3,4。为了达到这个目的,我写了一个lambda表达式:

private string GetCheckedIDs(CheckBoxList chkLst)
{
    string chkedVal = string.Empty;
    ((List<string>)chkLst.Items.OfType<ListItem>().Where(s => s.Selected).Select(s => s.Value))
                                                                         .ForEach(item => chkedVal = item + ",");
   return chkedVal.Remove(chkedVal.LastIndexOf(","));
}

我得到的错误是:

Unable to cast object of type
'WhereSelectEnumerableIterator`2[System.Web.UI.WebControls.ListItem,System.String]' to type 'System.Collections.Generic.List`1[System.String]'.

2 个答案:

答案 0 :(得分:4)

你的lambda表达式没有问题 - 问题是从IEnumerable<String>List<String>的转换你不能转换为列表,但这应该有效:

chkLst.Items.OfType<ListItem>()
      .Where(s => s.Selected)
      .Select(s => s.Value).ToList()
      .ForEach(item =>   chkedVal = item + ",");

这是一个更好的选择,使用String.Join(String, IEnumerable<String>)。它仍然选择字符串,但避免字符串连接(和最后一个逗号!):

string chkedVal = String.Join(",", chkLst.Items.OfType<ListItem>()
                                    .Where(s => s.Selected).Select(s => s.Value))

或者在.Net 3.5上你没有那么方便的重载 - 你需要为String.Join(String, String[])创建一个数组:

string chkedVal = String.Join(",", chkLst.Items.OfType<ListItem>()
                                     .Where(s => s.Selected)
                                     .Select(s => s.Value).ToArray())

答案 1 :(得分:1)

代码可以编译,但是你会在运行时得到那个错误。这是因为Linq返回的IEnumerable<string>实际上不是列表。这是出于性能原因,否则Linq必须预先构建整个列表,而不是根据需要构建每个项目。

IEnumerable<T>上有一个Linq方法迫使Linq预先建立列表 - ToList

chkLst.Items
    .OfType<ListItem>()
    .Where(s => s.Selected)
    .Select(s => s.Value)
    .ToList()
    .ForEach(item => chkedVal = item + ",");