2012-07-04 2 views
12

Я пытаюсь кодировать метод расширения Linq MinByC# тест, если переменная назначена

public static class Extensions 
{ 
    public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector) 
    { 
     T min; 
     int? minKey = null; 
     foreach (var x in source) 
     { 
      var key = selector(x); 
      if (minKey == null || key < minKey) 
      { 
       minKey = key; 
       min = x; 
      } 
     } 
     if (minKey == null) 
     { 
      throw new ArgumentException("source should not be empty"); 
     } 
     return min; 
    } 
} 

Я думаю, что моя логика верна и для чтения. Но я получаю сообщение об ошибке сборки

Использование неназначенной локальной переменной «мин»

Что я могу сделать по этому поводу? Могу ли я проверить, назначена ли переменная?


Уточнение: функция MinBy может ответить на следующий вопрос. Какое из чисел [-5, -2, 3] имеет наименьший квадрат?

> new List<int>{-5,-2,3}.MinBy(x => x*x) 
-2 

функция .NET в Min отвечает на другой вопрос (который является наименьшим из квадратов)

> new List<int>{-5,-2,3}.Min(x => x*x) 
4 
+0

IQueryable <> был бы даже лучше IEnumerable <> imho для этого. – Alex

+0

Что такое IQueryable? –

+0

Проверьте это на MSDN, это тип коллекции, который позволяет цепочку запросов, очень мощный. – Alex

ответ

23

Вам нужно значение по умолчанию для min так:

T min = default(T);

You can read more about default() on MSDN:

Учитывая переменную t параметризованного типа T, оператор t = null действителен только в том случае, если T является ссылочным типом, а t = 0 будет работать только для числовых типов значений , но не для структур. Решение заключается в использовании ключевого слова по умолчанию , которое вернет значение null для ссылочных типов и для числовых типов значений. Для structs он возвращает каждому члену структуру, инициализированную нулем или нулем, в зависимости от того, являются ли они значениями или ссылочными типами . Для типов значений с нулевым значением по умолчанию возвращается значение System.Nullable, которое инициализируется как любая структура.

+0

Спасибо. Разве это нарушает мою логику? После небольшой мысли нет. –

1

Это потому, что min назначается внутри условия. Компилятор не может определить, получит ли он значение или нет, вы должны инициализировать min с помощью значения default.

4

Добавить значение по умолчанию для min:

T min = default(T); 

Причина, жалуется, что компилятор не может проверить, что min будет присвоено значение, прежде чем он используется в return min; линии. Непризнанная локальная переменная не может быть указана, поэтому компилятор генерирует ошибку.

-1

FYI это то, что я закончил с

public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector) 
    { 
     T min = default(T); 
     bool started = false; 
     int minKey = default(int); 
     foreach (var x in source) 
     { 
      var key = selector(x); 
      if (!started || key < minKey) 
      { 
       minKey = key; 
       min = x; 
       started = true; 
      } 
     } 
     if (!started) 
     { 
      throw new ArgumentException("source should not be empty","source"); 
     } 
     return min; 
    } 
-1

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

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