3

Why is array still null after queried by DefaultIfEmpty ?

class Program
{
    static void Main(string[] args)
    {
        Program[] array = new Program[5];
        Program[] query = array.DefaultIfEmpty(new Program()).ToArray();
        foreach (var item in query)
        {
            Console.WriteLine(item.ToString());
        }
        Console.ReadKey();
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Freshblood
  • 6,285
  • 10
  • 59
  • 96

2 Answers2

5

Your array isn't empty - it's got 5 elements, each of which has a null value.

Note that array itself isn't null - and neither is query. But each element of them is null.

A truly empty array would have 0 elements:

using System;
using System.Linq;

class Program
{

    static void Main(string[] args)
    {
        Program[] array = new Program[0];
        Program[] query = array.DefaultIfEmpty(new Program()).ToArray();
        foreach (var item in query)
        {
            Console.WriteLine(item.ToString());
        }
        Console.ReadKey();
    }
}

Another alternative would be to filter null elements while you're copying the array:

Program[] query = array.Where(x => x != null)
                       .DefaultIfEmpty(new Program())
                       .ToArray();

EDIT: Perhaps you misunderstood the purpose of DefaultIfEmpty? This works on the whole sequence, not on an individual element basis. The idea isn't to replace null elements with a default value; it's to make sure that the result sequence is never empty. If you want to do a simple "replace null with a new value" you can do:

Program[] query = array.Select(x => x ?? new Program())
                       .ToArray();

Note that this will create a new value of Program for each null element; if you only want to create a single instance of Program and use multiple references to that, one for each originally null element, you could do this:

Program defaultValue = new Program();
Program[] query = array.Select(x => x ?? defaultValue)
                       .ToArray();
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Right i wanted to say my Array elements instead of array – Freshblood Jun 13 '10 at 07:50
  • Expected none-null elements after query but still all null – Freshblood Jun 13 '10 at 07:51
  • 1
    @Freshblood: Why would you only expect non-null elements? You haven't *asked* for only non-null elements, you've just said "if the input sequence has no elements, provide a default one in the result sequence". See my edit for how to get only non-null elements. – Jon Skeet Jun 13 '10 at 07:53
  • I am trying to assign default value for them if they empty(null) but this code doesn't provide it to me – Freshblood Jun 13 '10 at 07:53
  • @Freshblood: Basically you've misunderstood the purpose of the DefaultIfEmpty method. Read the docs carefully, and the bottom part of my answer. – Jon Skeet Jun 13 '10 at 07:54
  • Still i am reading documantation for understand purpose of DefaultIfEmpty :) – Freshblood Jun 13 '10 at 08:15
  • Purpose of my sample code wasn't assign none-null values to array elements.Purpose was understand purpose of DefaultIfEmpty.Already i could assign them default values as u gave some samples to me . – Freshblood Jun 13 '10 at 08:18
  • DefaultIfEmpty returns his input value If returning Array has no elements.Am i right ? – Freshblood Jun 13 '10 at 08:50
  • @Freshblood: It always returns a sequence. If the original sequence is empty, the result sequence contains the default value (either the type's default value, or the one specified as an argument). If the original sequence *isn't* empty, the result sequence contains the same elements as the original sequence. – Jon Skeet Jun 13 '10 at 08:57
  • Ah sequence is mean a collection which contains elements ... so i understand it just returns collection which contains one element if DefualtIfEmpty works . – Freshblood Jun 13 '10 at 09:46
  • Finally i have understood. Thanks for your effort – Freshblood Jun 13 '10 at 12:48
3

It sounds like you just want:

var query = Array.ConvertAll(array, item => item ?? new Program());
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900