Ответ 1
Ну, два аспекта:
- Как вы преобразовываете массив из одного типа в другой?
- Как вы преобразовываете строку в nullable int?
Первое простое - вы можете использовать Array.ConvertAll
, передавая делегат Converter
. Также существует способ LINQ (x.Select(...).ToArray()
), но это немного менее эффективно, если вы знаете, что у вас есть массив, и вы хотите, чтобы массив вышел из другого конца 1.
string
to int?
, вероятно, лучше всего сделать в методе. Вы можете сделать это в анонимной функции, но в этом конкретном случае я бы использовал отдельный метод. Мне редко нравится объявлять переменные в анонимной функции.
public static int? TryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? value : (int?) null;
}
Чтобы ответить на комментарий, да, вам нужно использовать листинг 2.
или без условного:
public static int? TryParseInt32(string text)
{
int value;
if (int.TryParse(text, out value))
{
return value;
}
else
{
return null;
}
}
Соедините их следующим образом:
string[] x = {"15", "10", "hello", "5" };
int?[] y = Array.ConvertAll(x, TryParseInt32);
1Array.ConvertAll
более эффективен, чем x.Select().ToArray()
, потому что он имеет больше информации. Он может сразу создать конечный массив - не требуется изменение размера. Вызов Enumerable.ToArray()
(с результатом Select()
) не имеет одинаковой информации, поэтому он должен добавить результаты к List<T>
(потенциально изменяя несколько раз по пути), а затем обычно изменять размер в конце также. (На самом деле он не использует List<T>
, но понятия одинаковы.) Это определенно стоит знать о решении Select/ToArray, но я не думаю, что в этом случае он будет более читабельным, чем ConvertAll
, поэтому вы может также использовать более эффективную форму.
2 Причина, по которой вам нужен приведение в условном выражении, заключается в том, что компилятор не знает, какой тип "нуль" вы действительно имеете в виду, но он знает, что он не может преобразовать из null
до int
. Тип условного выражения должен быть либо типом второго операнда, либо типом третьего операнда, а другой должен быть неявно конвертируемым. Заставляя третий операнд иметь тип int?
здесь все в порядке - потому что вы можете неявно конвертировать из int
в int?
. Обратите внимание, что компилятор не использует то, как вы используете выражение, чтобы попытаться определить тип. Другой альтернативой является использование new int?()
вместо null
.