Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
int.TryParse
, вероятно, немного легче:
public static int? ToNullableInt(this string s)
{
int i;
if (int.TryParse(s, out i)) return i;
return null;
}
Редактирование @Glenn int.TryParse
"встроен в платформу". Это и int.Parse
способ проанализировать строки к ints.
Вы должны никогда , используют исключение, если Вы не имеете к - издержки ужасны.
изменения на TryParse решают проблему - если Вы хотите стать творческими (чтобы заставить Ваш код выглядеть более изящным), Вы могли бы, вероятно, сделать что-то с дополнительным методом в 3,5 кроме кода, будет более или менее то же.
я интересуюсь больше знанием, если существует встроенный метод платформы, который проанализирует непосредственно в nullable интервал?
нет.
Попробуйте это:
public static int? ParseNullableInt(this string value)
{
int intValue;
if (int.TryParse(value, out intValue))
return intValue;
return null;
}
У меня была эта проблема, я закончил с этим (в конце концов, if
и 2 return
, с таким образом многоречива!):
int? ParseNInt (string val)
{
int i;
return int.TryParse (val, out i) ? (int?) i : null;
}
На более серьезной ноте, попытайтесь не смешаться int
, который является ключевым словом C#, с Int32
, который является Платформой.NET тип BCL - хотя он работает, он просто заставляет код выглядеть грязным.
Можно сделать это в одной строке, с помощью условного оператора и того, что можно бросить null
к nullable типу (две строки, если у Вас нет существующего ранее интервала, можно снова использовать для вывода TryParse
):
Пред C#7:
int tempVal;
int? val = Int32.TryParse(stringVal, out tempVal) ? Int32.Parse(stringVal) : (int?)null;
С обновленным синтаксисом C#7, который позволяет Вам объявлять выходную переменную в вызове метода, это становится еще более простым.
int? val = Int32.TryParse(stringVal, out var tempVal) ? tempVal : (int?)null;
Используя делегаты, следующий код может обеспечить возможность многократного использования, если вам потребуется синтаксический анализ, допускающий значение NULL, для более чем одного типа структуры. Я показал здесь обе версии .Parse () и .TryParse ().
Это пример использования:
NullableParser.TryParseInt(ViewState["Id"] as string);
А вот код, который приведет вас туда ...
public class NullableParser
{
public delegate T ParseDelegate<T>(string input) where T : struct;
public delegate bool TryParseDelegate<T>(string input, out T outtie) where T : struct;
private static T? Parse<T>(string input, ParseDelegate<T> DelegateTheParse) where T : struct
{
if (string.IsNullOrEmpty(input)) return null;
return DelegateTheParse(input);
}
private static T? TryParse<T>(string input, TryParseDelegate<T> DelegateTheTryParse) where T : struct
{
T x;
if (DelegateTheTryParse(input, out x)) return x;
return null;
}
public static int? ParseInt(string input)
{
return Parse<int>(input, new ParseDelegate<int>(int.Parse));
}
public static int? TryParseInt(string input)
{
return TryParse<int>(input, new TryParseDelegate<int>(int.TryParse));
}
public static bool? TryParseBool(string input)
{
return TryParse<bool>(input, new TryParseDelegate<bool>(bool.TryParse));
}
public static DateTime? TryParseDateTime(string input)
{
return TryParse<DateTime>(input, new TryParseDelegate<DateTime>(DateTime.TryParse));
}
}
Я нашел и адаптировал некоторый код для класса Generic NullableParser. Полный код находится в моем блоге Nullable TryParse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace SomeNamespace
{
/// <summary>
/// A parser for nullable types. Will return null when parsing fails.
/// </summary>
/// <typeparam name="T"></typeparam>
///
public static class NullableParser<T> where T : struct
{
public delegate bool TryParseDelegate(string s, out T result);
/// <summary>
/// A generic Nullable Parser. Supports parsing of all types that implements the tryParse method;
/// </summary>
/// <param name="text">Text to be parsed</param>
/// <param name="result">Value is true for parse succeeded</param>
/// <returns>bool</returns>
public static bool TryParse(string s, out Nullable<T> result)
{
bool success = false;
try
{
if (string.IsNullOrEmpty(s))
{
result = null;
success = true;
}
else
{
IConvertible convertableString = s as IConvertible;
if (convertableString != null)
{
result = new Nullable<T>((T)convertableString.ToType(typeof(T),
CultureInfo.CurrentCulture));
success = true;
}
else
{
success = false;
result = null;
}
}
}
catch
{
success = false;
result = null;
}
return success;
}
}
}
Я понимаю, что это старая тема, но разве вы не можете просто:
(Nullable<int>)int.Parse(stringVal);
?
Следующее должно работать для любого типа структуры. Он основан на коде Мэтта Манелы с форумов MSDN . Как указывает Мерф, обработка исключений может быть дорогостоящей по сравнению с использованием специального метода TryParse для типов.
public static bool TryParseStruct<T>(this string value, out Nullable<T> result)
where T: struct
{
if (string.IsNullOrEmpty(value))
{
result = new Nullable<T>();
return true;
}
result = default(T);
try
{
IConvertible convertibleString = (IConvertible)value;
result = new Nullable<T>((T)convertibleString.ToType(typeof(T), System.Globalization.CultureInfo.CurrentCulture));
}
catch(InvalidCastException)
{
return false;
}
catch (FormatException)
{
return false;
}
return true;
}
Это были основные тестовые примеры, которые я использовал.
string parseOne = "1";
int? resultOne;
bool successOne = parseOne.TryParseStruct<int>(out resultOne);
Assert.IsTrue(successOne);
Assert.AreEqual(1, resultOne);
string parseEmpty = string.Empty;
int? resultEmpty;
bool successEmpty = parseEmpty.TryParseStruct<int>(out resultEmpty);
Assert.IsTrue(successEmpty);
Assert.IsFalse(resultEmpty.HasValue);
string parseNull = null;
int? resultNull;
bool successNull = parseNull.TryParseStruct<int>(out resultNull);
Assert.IsTrue(successNull);
Assert.IsFalse(resultNull.HasValue);
string parseInvalid = "FooBar";
int? resultInvalid;
bool successInvalid = parseInvalid.TryParseStruct<int>(out resultInvalid);
Assert.IsFalse(successInvalid);