Что не так с моим лямбда-выражением - PullRequest
2 голосов
/ 16 марта 2011

Я хочу получить строку из отмеченных значений selectedListbox, например, 1,3,4. Для этого я написал лямбда-выражение:

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 ]

4 голосов
/ 16 марта 2011

Нет ничего плохого в вашем лямбда-выражении - проблема в приведении от 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 голос
/ 16 марта 2011

Код может скомпилироваться, но вы получите эту ошибку во время выполнения. Это потому, что IEnumerable<string>, возвращаемое Linq, на самом деле не является списком. Это из соображений производительности, иначе Linq должен был бы создать весь список заранее, вместо того, чтобы создавать каждый элемент по мере необходимости.

Существует метод Linq на IEnumerable<T>, который заставляет Linq строить список заранее, однако - ToList:

chkLst.Items
    .OfType<ListItem>()
    .Where(s => s.Selected)
    .Select(s => s.Value)
    .ToList()
    .ForEach(item => chkedVal = item + ",");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...