2015-01-08 2 views
-3

Проблема с методом ниже. Текущая ошибка, которую я получаю, это «она не возвращает никакого значения». Если я помещаю возвращаемое число вне скобок, оно не существует в текущем контексте. Если удалить скобки все вместе я получаю:Использование случайного rnd внутри метода вызывает несколько ошибок

Встроенный оператор не может быть декларация или помеченный оператор Название «RND» не существует в текущем контексте

Я сделал несколько методов, прежде чем без этого вопрос. Что мне не хватает?

public static int generateNumber(int timesUserWantsToGuess) 
     { 
      for (int i = 0; i <= timesUserWantsToGuess; i++) 
      { 
       Random rnd = new Random(); 
       int num = rnd.Next(1, 50); 
       return num; 
      } 


     } 
+5

Что происходит, когда 'timesUserWantsToGuess = 0'? Компилятор просто отвергает эту возможность. Сначала исправьте первую ошибку и, пожалуйста, * search * для сообщений об ошибках. – user2864740

+0

Что вы пытаетесь выполнить с помощью этого метода? Если 'timesUserWantsToGuess' равно 0, цикл не вернет значение. Если 'timesUserWantsToGuess' => 1, то цикл будет выполнен только один раз. Тогда есть целая проблема с объявлением новой «Случайной» на итерацию, которая собирается (более чем вероятно) производить одно и то же случайное число. – Cameron

+0

Также рассмотрите случай, когда 'timesUserWantsToGuess <0'.Компилятор не знает, что это недопустимое значение для передачи этой функции. –

ответ

6

Прежде всего у вас есть несоответствие семантики. Вы возвращаете один int, но выполняете и возвращаете в цикле.

Если вы на самом деле хотел вернуть коллекцию целых чисел, вы могли бы сделать что-то вроде этого:

public static IEnumerable<int> generateNumber(int timesUserWantsToGuess) 
{ 
    //Optional, but good error checking 
    if (timesUserWantsToGuess <= 0) 
     throw new ArgumentException("Invalid guess count"); 

    Random rnd = new Random(); 
    for (int i = 0; i < timesUserWantsToGuess; i++) 
    { 
     int num = rnd.Next(1, 50); 
     yield return num; 
    } 
} 

Обратите внимание на использование yield вернуть следующий объект в последовательности. Вы также не должны создавать экземпляр Random в замкнутом цикле, поскольку он будет генерировать одинаковые значения (одно и то же семя). Кроме того, использование <= в условном выражении даст еще одну итерацию, чем переданное значение, поэтому я переключился на <.

Если вы вообще не хотите петли, просто удалите ее, и ваша проблема будет решена. На данный момент семантика цикла и остальная часть вашего несоответствия кода, что вызывает у вас проблему.

+0

Он может (или не должен) также стоить добавить проверку 'timeUserWantsToGuess <0' и выкидывать' InvalidOperationException', а не просто возвращать пустую последовательность, поскольку кажется, что это должна быть серьезная ошибка , –

+1

@MattBurland Согласен, хотя я бы использовал 'ArgumentException'. Добавлен как необязательный элемент – BradleyDotNET

0

Проблема заключается в том, что, поскольку оператор return существует внутри цикла, компилятор предполагает, что он может выполнить, не нажимая на блок, и, таким образом, не вернется. Это может произойти логически, если timesUserWantsToGuess меньше 0 - цикл в этом случае никогда не входит. Причина, по которой этот код компилируется, если оператор return находится за пределами блока, заключается в том, что, находясь за пределами блока, выполнение гарантирует, что оно достигнет return (или выбросит исключение) в какой-то момент.

Если убрать скобки на блоке в C# (if, for, foreach, lock и while все это сделать, насколько мне известно), вы говорите, что блок содержит только следующую строку (которая отступ по соглашению) и больше ничего. Поскольку объявление переменной в однострочном («внедренном») выражении нельзя использовать нигде иначе синтаксически, делать это не имеет смысла, поэтому компилятор запрещает его вообще. Следует отметить, что также можно объявить переменную в блоке, не используя ее, если блок заключен в скобки.

Наконец, есть огромное смысловое несоответствие в логике возвращение одного значения во время цикла, как это: см @ BradleyDotNET отвечает на yield return заявлении

+2

На самом деле он будет пропускать цикл 'for', если' timesUserWantsToGuess' меньше нуля. – juharr

+0

@juharr true, я обновлю свой ответ – David

Смежные вопросы