C#: LINQ
var str = "a b a";
var test = Enumerable.SequenceEqual(str.ToCharArray(),
str.ToCharArray().Reverse());
Для C # 7
В C # 7 throw
становится выражением, поэтому можно использовать именно тот код, который описан в вопросе.
Для C # 6 и ранее
Вы не можете сделать это напрямую в C # 6 и ранее - второй операнд ?? должно быть выражением, а не оператором throw.
Есть несколько альтернатив, если вы действительно просто пытаетесь найти краткий вариант:
Вы можете написать:
public static T ThrowException<T>()
{
throw new Exception(); // Could pass this in
}
А затем:
return command.ExecuteScalar() as int? ?? ThrowException<int?>();
Я действительно не рекомендую вам делать это, хотя ... это довольно ужасно и неидиоматично.
Как насчет метода расширения:
public static T ThrowIfNull(this T value)
{
if (value == null)
{
throw new Exception(); // Use a better exception of course
}
return value;
}
Затем:
return (command.ExecuteScalar() as int?).ThrowIfNull();
Еще одна альтернатива (снова расширение метод):
public static T? CastOrThrow<T>(this object x)
where T : struct
{
T? ret = x as T?;
if (ret == null)
{
throw new Exception(); // Again, get a better exception
}
return ret;
}
Вызов с помощью:
return command.ExecuteScalar().CastOrThrow<int>();
Это несколько некрасиво, потому что вы не можете указать int?
в качестве аргумента типа ...
Как уже было сказано, вы не можете сделать это с помощью ?? оператор (ну, не без некоторых искажений, которые, кажется, не подходят для вашей цели создания этого очистителя).
Когда я вижу, как появляется этот шаблон, я сразу думаю о Enforcements . Первоначально из мира C ++ они довольно хорошо переносятся на C #, хотя, возможно, в большинстве случаев они менее важны.
Идея состоит в том, что вы берете что-то в форме:
if( condition )
{
throw Exception;
}
и преобразуете его в:
Enforce<Exception>( condition );
(вы можете дополнительно упростить, установив тип исключения по умолчанию).
В дальнейшем вы можете написать набор методов в стиле Nunit для различных проверок условий, например,
Enforce<Exception>.NotNull( obj );
Enforce<Exception>.Equal( actual, expected );
Enforce<Exception>.NotEqual( actual, expected );
и т. д.
Или, что еще лучше, предоставив лямбу ожидания:
Enforce<Exception>( actual, expectation );
Что действительно здорово, так это то, что как только вы это сделаете, вы можете вернуть фактический параметр и применить inline :
return Enforce( command.ExecuteScalar() as Int32?, (o) => o.HasValue ).Value;
... и это похоже на то, что вам нужно.
Я постучал. до реализации этого раньше. Есть пара мелких проблем, например, как вы в общем случае создаете объект исключения, который принимает аргументы - некоторые варианты там (я выбрал отражение в то время, но передача фабрики в качестве дополнительного параметра может быть даже лучше). Но в целом все довольно просто и может действительно очистить много кода.
Это в моем списке вещей, которые нужно сделать, чтобы создать реализацию с открытым исходным кодом.
например, как вы в общем создаете объект исключения, который принимает аргументы - некоторые варианты там (я выбрал отражение в то время, но передача фабрики в качестве дополнительного параметра может быть даже лучше). Но в целом все довольно просто и может действительно очистить много кода.Это в моем списке вещей, которые необходимо сделать, чтобы создать реализацию с открытым исходным кодом.
например, как вы обычно создаете объект исключения, который принимает аргументы - некоторые варианты там (я выбрал отражение в то время, но передача фабрики в качестве дополнительного параметра может быть даже лучше). Но в целом все довольно просто и может действительно очистить много кода.Это в моем списке вещей, которые нужно сделать, чтобы создать реализацию с открытым исходным кодом.
Если вам просто нужно исключение, когда возвращаемое значение не является Int32
, сделайте следующее:
return (int)command.ExecuteScalar();
Если вы хотите создать собственное исключение, тогда я d, вероятно, вместо этого сделайте что-то вроде этого:
int? result = command.ExecuteScalar() as int?;
if (result == null) throw new YourCustomException();
return result.Value;
Вы не сможете генерировать исключение в правой части оператора объединения с нулевым значением. Причина в том, что правая часть оператора должна быть выражением, а не утверждением.
Оператор объединения с нулевым значением работает следующим образом: если левое значение оператора равно нулю, вернуть его; в противном случае верните то, что находится справа от оператора. Ключевое слово throw
не возвращает значения; следовательно, его нельзя использовать в правой части оператора.
Причина, по которой вы не можете этого сделать:
return command.ExecuteScalar() as Int32? ?? throw new Exception();
Это потому, что генерирование исключения - это оператор, а не выражение.
Если вы просто хотите немного сократить код , возможно это:
var result = command.ExecuteScalar() as Int32?;
if(result.HasValue) return result;
throw new Exception();
В остальном нет необходимости.