LINQ: невозможно неявно преобразовать тип «System.Collections.Generic.IEnumerable‹int›» в «int»

Я получаю сообщение об ошибке из следующего кода:

int dreamX[];

private void Form1_Load(object sender, EventArgs e)
{ 
    sumX();
}

private void sumX()
{
    for (var i = 0; i < 8; i++)
    {
        dreamX[i] =
            from Control control in Controls
            where
                control.GetType() == typeof(TextBox)
                && control.Name.StartsWith("box")
            select Convert.ToInt32(((TextBox)control).Text);
    }
}

Я получаю эту ошибку, как это явно преобразовать.

"Невозможно неявно преобразовать тип System.Collections.Generic.IEnumerable -int-" в "int"


person Darkmage    schedule 28.09.2009    source источник
comment
Гм, как ты вообще получил int dreamX[]; компилировать? Что это должно значить?   -  person Joel Mueller    schedule 28.09.2009
comment
@Joel: дай парню передышку! Он учится и явно получает удовольствие.   -  person Dabblernl    schedule 28.09.2009


Ответы (4)


Что вы хотите, так это:

int[] dreamX;
private void Form1_Load(object sender, EventArgs e)
        { 
         sumX();
        }
 private void sumX()
        {
                dreamX =( from Control control in Controls                  
                         where control.GetType() == typeof(TextBox) &&
                               control.Name.StartsWith("box")
                         select Convert.ToInt32(((TextBox)control).Text))
                                       .ToArray();             
        }

Предложение from создает коллекцию IEnumerable. Вы можете преобразовать это в массив с расширением .ToArray()

person Dabblernl    schedule 28.09.2009

Что ж, этот запрос может возвращать более одного значения, поэтому вам нужно либо использовать .Single() , .First() или .FirstOrDefault() методов расширения.

Обратите внимание, что Single() будет работать, только если в списке есть ровно один элемент, First() будет работать, только если в списке есть по крайней мере один элемент. FirstOrDefault() возвращается к значению по умолчанию (0), если в списке нет элемента.

В зависимости от того, что именно вам нужно, вам и придется выбирать :)

person Joey    schedule 28.09.2009

Столько всего неправильного в этом.

Прежде всего, вы пытаетесь присвоить потенциально множество преобразованных целых чисел одному целому в массиве. Это то, о чем говорит вам сообщение об ошибке.

Кроме того, нигде в показанном вами коде этот массив никогда не инициализировался. Поэтому, даже если вы вызовете что-то вроде .FirstOrDefault(), вы получите NullReferenceException. Лучше вообще не использовать массивы, если можете. Просто придерживайтесь IEnumerable.

Кроме того, у вашего запроса linq есть дополнительный шаг; вместо того, чтобы проверять тип каждого элемента управления в коллекции Controls, вы должны вызвать его метод .OfType().

Наконец, прелесть linq в том, что вам даже не нужно писать цикл for. Вы можете просто написать одно выражение, которое оценивает все ваши текстовые поля.

IEnumerable<int> dreamX;

private void Form1_Load(object sender, EventArgs e)
{ 
    sumX();
    int totalX = dreamX.Sum();
}

private void sumX()
{
    dreamX = from control in Controls.OfType<TextBox>()
             where control.Name.StartsWith("box")
             select Convert.ToInt32(control.Text);
}
person Joel Coehoorn    schedule 28.09.2009

FirstOrDefault() превратит IEnumerable<int> в int.

На самом деле он занимает первое место в результатах вывода вашего linq-запроса.

person Natrium    schedule 28.09.2009
comment
Только если есть хотя бы один элемент :-). В противном случае он возвращает 0. - person Joey; 28.09.2009