Oto kod z odpowiedzi Marca Gravella wraz z przykładem jego użycia.
using System;
using System.Collections.Generic;
using System.Linq;
public static class Utils
{
public static bool IsAny<T>(this IEnumerable<T> data)
{
return data != null && data.Any();
}
}
class Program
{
static void Main(string[] args)
{
IEnumerable<string> items;
//items = null;
//items = new String[0];
items = new String[] { "foo", "bar", "baz" };
/*** Example Starts Here ***/
if (items.IsAny())
{
foreach (var item in items)
{
Console.WriteLine(item);
}
}
else
{
Console.WriteLine("No items.");
}
}
}
Jak mówi, nie wszystkie sekwencje są powtarzalne, więc kod może czasami powodować problemy, ponieważ IsAny()
zaczyna przechodzić przez sekwencję. Podejrzewam, że odpowiedź Roberta Harveya oznaczała, że często nie trzeba sprawdzać null
i opróżniać. Często wystarczy sprawdzić wartość null, a następnie użyć foreach
.
Aby uniknąć dwukrotnego uruchamiania sekwencji i skorzystać z tego foreach
, po prostu napisałem kod podobny do tego:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
IEnumerable<string> items;
//items = null;
//items = new String[0];
items = new String[] { "foo", "bar", "baz" };
/*** Example Starts Here ***/
bool isEmpty = true;
if (items != null)
{
foreach (var item in items)
{
isEmpty = false;
Console.WriteLine(item);
}
}
if (isEmpty)
{
Console.WriteLine("No items.");
}
}
}
Wydaje mi się, że metoda rozszerzenia pozwala zaoszczędzić kilka wierszy pisania, ale ten kod wydaje mi się bardziej przejrzysty. Podejrzewam, że niektórzy programiści nie od razu zorientują się, że IsAny(items)
faktycznie zaczną przechodzić przez sekwencję. (Oczywiście, jeśli używasz wielu sekwencji, szybko nauczysz się myśleć o tym, co przez nie przechodzi).