Я устал от использования такого кода :
var count = 0;
if (myEnumerable != null)
{
count = myEnumerable.Count();
}
И это немного педантично:
var count = (myEnumerable ?? new string[0]).Count();
Есть ли более аккуратный способ сделать это? Однажды у меня был (плохо названный) метод расширения PhantomCount в IEnumerable <>, который использовал мой первый пример кода, но от него что-то пахло (помимо имени).
Проблема на самом деле в том, кто создает эти перечислимые. Если у вас нет действительно веской причины, все, что создает итерируемую коллекцию, должно возвращать пустую коллекцию вместо null
. Это согласуется с Null-Object-Pattern, следовательно, польза та же.
Мое предложение - исправить все, что производит myEnumerable
, или, если вы не можете этого сделать, добавить проверку way раньше, чтобы увидеть, является ли он null, и реагировать соответствующим образом.
Я не думаю, что использовать расширение метод - плохая идея.
public static int NullableCount<T>(this IEnumerable<T> collection)
{
return collection == null ? 0 : collection.Count();
}
Как насчет
count = myEnumerable == null? 0 : myEnumerable.Count()
Я использую специальный метод расширения:
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
...
int count = myEnumerable.EmptyIfNull().Count();
Просто создайте свой собственный метод расширения, который обрабатывает нулевые перечисления по своему усмотрению.
public int CountOrNull<T>(this IEnumerable<T> source)
{
return source == null ? 0 : source.Count();
}
Затем вы можете просто использовать:
var list1 = new int[] { 1, 2, 3, 4 };
var list2 = (int[])null;
var count1 = list1.CountOrNull(); // 4
var count2 = list2.CountOrNull(); // 0
Это самое замечательное в методах расширения. Они по-прежнему работают нормально, даже если объект, для которого (кажется, вы) вызываете метод, имеет значение null
.
Какие действия вы предпринимаете, если возвращаемое значение равно 0?
Если это интересно, возможно, вам стоит использовать метод расширения Haack IsNullOrEmpty
для IEnumerable
, например:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
return items == null || !items.Any();
}
Ссылка http://haacked.com/archive/2010/06/10/checking-for-empty-enumerations.aspx
В комментариях к блогу вы также найдете Exception
класс, который я написал для этого:
public class ArgumentNullOrEmptyException : ArgumentNullException
{
public ArgumentNullOrEmptyException( string paramName ) : base( paramName )
{}
public ArgumentNullOrEmptyException( string paramName, string message ) : base( paramName, message )
{}
public override string Message
{
get
{
return "Value cannot be null nor empty.{0}Parameter name: {1}".FormatWith( Environment.NewLine, ParamName );
}
}
}
Я бы также написал свой собственный метод расширения CountOrZeroForNull
, как показано в других ответах.
Кроме того ... Вместо:
var count = (myEnumerable ?? new string[0]).Count();
// ^^^^^^^^^^^^^
вы можете написать:
var count = (myEnumerable ?? Enumerable.Empty<string>()).Count();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
Это не решает вашу конкретную проблему, но позволяет избежать выделения неиспользуемого массива. ( Enumerable.Empty
, скорее всего, реализован как простой оператор yield break
.)
var count = 0;
if (myEnumerable != null)
count = myEnumerable.Count();
Хотя он не такой технический, как другие ответы, он намного удобнее всего для чтения.