Costumo encontrar códigos como o seguinte:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
Basicamente, a if
condição garante que o foreach
bloco será executado apenas se items
não for nulo. Estou me perguntando se a if
condição é realmente necessária ou foreach
se tratarei do caso items == null
.
Quer dizer, posso simplesmente escrever
foreach(T item in items)
{
//...
}
sem se preocupar se items
é nulo ou não? A if
condição é supérflua? Ou isso depende do tipo de items
ou talvez em T
bem?
null
) generalizando todo o loop para o LCD deEnumerable
(como a utilização??
faria ), b) requerer a adição de um Método de Extensão para cada Projeto, ou c) Requer evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para começar com (cuz,null
significa N / A, enquanto lista vazia significa, é aplicável. mas é atualmente, bem, vazio !, ou seja, um funcionário pode ter comissões que são N / A para não vendas ou vazio para vendas quando não ganhou nenhuma).Respostas:
Você ainda precisa verificar se (items! = Null), caso contrário, você obterá NullReferenceException. No entanto, você pode fazer algo assim:
mas você pode verificar o desempenho dele. Portanto, ainda prefiro ter if (items! = Null) primeiro.
Com base na sugestão de Eric Lippert, mudei o código para:
fonte
IEnumerable<T>
que, por sua vez, degrada para enumerador para uma interface, tornando a iteração mais lenta. Meu teste mostrou uma degradação de fator 5 para iteração em uma matriz int.Usando C # 6, você pode usar o novo operador condicional nulo junto com
List<T>.ForEach(Action<T>)
(ou seu próprioIEnumerable<T>.ForEach
método de extensão).fonte
null
) generalizar todo o loop para o LCD deEnumerable
(como??
faria), b) requer a adição de um Método de extensão para cada projeto, ou c ) exigem evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para começar com (cuz,null
significa N / A, enquanto lista vazia significa, é aplicável, mas está atualmente, bem, vazio !, ou seja, um funcionário pode ter Comissões que são N / A para não vendas ou vazio para vendas quando não houver ganho).items
seja um pensamentoList<T>
, e não qualquer umIEnumerable<T>
. (Ou tenha um método de extensão personalizado, que você disse que não queria que houvesse ...) Além disso, eu diria que realmente não vale a pena adicionar 11 comentários, todos basicamente dizendo que você gosta de uma resposta específica.foreach
. Particularmente para uma lista que eu acho que é convertida em umfor
loop.A verdadeira lição aqui deve ser uma sequência quase nunca deve ser nula em primeiro lugar . Basta torná-lo uma invariante em todos os seus programas para que, se você tiver uma sequência, ela nunca seja nula. É sempre inicializado para ser a sequência vazia ou alguma outra sequência genuína.
Se uma sequência nunca for nula, obviamente você não precisa verificá-la.
fonte
null
) generalizando todo o loop para o LCD deEnumerable
(como a utilização??
faria ), b) requerer a adição de um Método de Extensão para cada Projeto, ou c) Requer evitarnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) para começar com (cuz,null
significa N / A, enquanto lista vazia significa, é aplicável. mas é atualmente, bem, vazio !, ou seja, um funcionário pode ter comissões que são N / A para não vendas ou vazio para vendas quando não ganhou nenhuma).Na verdade, há uma solicitação de recurso nesse @Connect: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
E a resposta é bastante lógica:
fonte
Você sempre pode testar com uma lista nula ... mas isso é o que eu encontrei no site do msdn
fonte
Não é supérfluo. No tempo de execução, os itens serão lançados em um IEnumerable e seu método GetEnumerator será chamado. Isso causará uma desreferenciação de itens que falharão
fonte
IEnumerable
e 2) É uma decisão de design fazer o lançamento. C # poderia inserir facilmente essenull
cheque se os desenvolvedores considerassem isso uma boa ideia.Você pode encapsular a verificação nula em um método de extensão e usar um lambda:
O código se torna:
Pode ser ainda mais conciso se você quiser apenas chamar um método que pega um item e retorna
void
:fonte
Você precisa disso. Você obterá uma exceção ao
foreach
acessar o contêiner para configurar a iteração de outra forma.Nos bastidores,
foreach
usa uma interface implementada na classe de coleção para realizar a iteração. A interface genérica equivalente está aqui .fonte
O teste é necessário, porque se a coleção for nula, foreach lançará uma NullReferenceException. Na verdade, é muito simples de experimentar.
fonte
o segundo vai lançar um
NullReferenceException
com a mensagemObject reference not set to an instance of an object.
fonte
Conforme mencionado aqui, você precisa verificar se não é nulo.
fonte
Em C # 6, você pode escrever sth assim:
É basicamente a solução de Vlad Bezden, mas usando o ?? expressão para sempre gerar uma matriz que não seja nula e, portanto, sobreviva a foreach, em vez de ter essa verificação dentro do colchete foreach.
fonte