Тест С#, если назначена переменная
Я пытаюсь закодировать метод расширения Linq MinBy
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;
}
}
Я думаю, что моя логика правильная и читаемая. Но я получаю ошибку сборки
Использование неназначенной локальной переменной 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
Ответы
Ответ 1
Для min
вам нужно значение по умолчанию:
T min = default(T);
Вы можете узнать больше о default()
в MSDN:
Учитывая переменную t параметризованного типа T, оператор t = null действует только в том случае, если T является ссылочным типом, а t = 0 будет работать только для числовые значения, но не для структур. Решение состоит в том, чтобы использовать ключевое слово по умолчанию, которое будет возвращать значение null для ссылочных типов и ноль для числовых значений. Для структур будет возвращен каждый член структура, инициализированная нулем или нулем, в зависимости от того, являются ли они значения или ссылочные типы. Для типов значений с нулевым значением значение по умолчанию возвращает System.Nullable, который инициализируется как любая структура.
Ответ 2
Добавьте значение по умолчанию для min
:
T min = default(T);
Причина, по которой он жалуется, заключается в том, что компилятор не может проверить, что min
будет присвоено значение до его использования в строке return min;
. Непризнанная локальная переменная не может быть указана, поэтому компилятор генерирует ошибку.
Ответ 3
Это потому, что в этом условии min назначается. Компилятор не может определить, получит ли он значение или нет, вы должны инициализировать min с значением по умолчанию.
Ответ 4
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;
}
Ответ 5
Нет, вы не можете проверить, назначена ли переменная, вы всегда получите ошибку компиляции.