Why does .NET foreach loop throw NullRefException when collection is null?

前端 未结 11 1863
长发绾君心
长发绾君心 2020-11-28 20:34

So I frequently run into this situation... where Do.Something(...) returns a null collection, like so:

int[] returnArray = Do.Something(...);


        
相关标签:
11条回答
  • 2020-11-28 21:12

    Just write an extension method to help you out:

    public static class Extensions
    {
       public static void ForEachWithNull<T>(this IEnumerable<T> source, Action<T> action)
       {
          if(source == null)
          {
             return;
          }
    
          foreach(var item in source)
          {
             action(item);
          }
       }
    }
    
    0 讨论(0)
  • 2020-11-28 21:17

    Another extension method to work around this:

    public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
    {
        if(items == null) return;
        foreach (var item in items) action(item);
    }
    

    Consume in several ways:

    (1) with a method that accepts T:

    returnArray.ForEach(Console.WriteLine);
    

    (2) with an expression:

    returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
    

    (3) with a multiline anonymous method

    int toCompare = 10;
    returnArray.ForEach(i =>
    {
        var thisInt = i;
        var next = i++;
        if(next > 10) Console.WriteLine("Match: {0}", i);
    });
    
    0 讨论(0)
  • 2020-11-28 21:17

    Because a null collection is not the same thing as an empty collection. An empty collection is a collection object with no elements; a null collection is a nonexistent object.

    Here's something to try: Declare two collections of any sort. Initialize one normally so that it's empty, and assign the other the value null. Then try adding an object to both collections and see what happens.

    0 讨论(0)
  • 2020-11-28 21:17
    SPListItem item;
    DataRow dr = datatable.NewRow();
    
    dr["ID"] = (!Object.Equals(item["ID"], null)) ? item["ID"].ToString() : string.Empty;
    
    0 讨论(0)
  • 2020-11-28 21:18

    Because behind the scenes the foreach acquires an enumerator, equivalent to this:

    using (IEnumerator<int> enumerator = returnArray.getEnumerator()) {
        while (enumerator.MoveNext()) {
            int i = enumerator.Current;
            // do some more stuff
        }
    }
    
    0 讨论(0)
  • 2020-11-28 21:26

    A foreach loop calls the GetEnumerator method.
    If the collection is null, this method call results in a NullReferenceException.

    It is bad practice to return a null collection; your methods should return an empty collection instead.

    0 讨论(0)
提交回复
热议问题