nothing collection in for each loop - how to handle it?
Do I need to wrap the foreach loop in a if to check for nothing and only if it is not nothing then enter in the for each loop?
Yes.
If MyStringList IsNot Nothing Then
For Each item As String In MyStringList
'do something ...
Next
End If
Microsoft says it is by design:
I think that most foreach loops are written with the intent of iterating a non-null collection. If you try iterating through null you should get your exception, so that you can fix your code. Foreach is basically a syntactic convenience. As such, it should not be "magical" and do unexpected things under the hood. I agree with the post that proposed the use of empty collections rather than null. (They can typically be reused quite a bit using singleton techniques).
Adding the If collection IsNot Nothing Then
is not that onerous, but if you do have this construct a lot, this Extension method may be preferable:
'''---------------------------------------------------------------------
''' Extension Function: OrEmpty
'''
''' <summary>
''' Returns an empty enumeration if the source is Nothing.
''' </summary>
'''
''' <typeparam name="T">The type to create an enumeration of. Normally inferred.</typeparam>
'''
''' <param name="Source">The source enumeration.</param>
'''
''' <returns>The source enumeration unless it is Nothing; then an empty enumeration.</returns>
'''
''' <remarks>
''' </remarks>
'''
''' <revisionhistory>
''' 100930 MEH Created.
''' </revisionhistory>
'''---------------------------------------------------------------------
<Extension()> _
Function OrEmpty(Of T)(ByVal Source As IEnumerable(Of T)) As IEnumerable(Of T)
If Source IsNot Nothing Then _
Return Source
Return Enumerable.Empty(Of T)()
End Function
And with Option Infer On
you don't need to specify the type, so the example use is just:
For Each item As String In MyStringList.OrEmpty
'do something with each item but something myStringList will be nothing?
Next
Do I need to wrap the foreach loop in a if to check for nothing and only if it is not nothing then enter in the for each loop?
Yeap, that's what you have to do. Or ensure that the function that returns the string list (if you have control over it) never returns a null array but an empty collection instead which by the way is the standard approach for functions returning collections - they should never be null as it makes them LINQ unfriendly and forces you to write ifs everywhere.