-3

In the following MSDN Official article on LINQ Outer Join, author(s) are using ? and ?? together in ...select new { person.FirstName, PetName = subpet?.Name ?? String.Empty };. Question: Why not just use ?? as: select new { person.FirstName, PetName = subpet.Name ?? String.Empty }; that, I think, translates to if subpet.Name is null give me empty string. Am I misunderstanding something?

Reason for the Inquiry: When I was using ? and ?? together in my code (explained here) the VS2015 Intellisense was giving me the error also explained in that post.

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}

public static void LeftOuterJoinExample()
{
    Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
    Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
    Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
    Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

    Pet barley = new Pet { Name = "Barley", Owner = terry };
    Pet boots = new Pet { Name = "Boots", Owner = terry };
    Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
    Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
    Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

    // Create two lists.
    List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
    List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

    var query = from person in people
                join pet in pets on person equals pet.Owner into gj
                from subpet in gj.DefaultIfEmpty()
                select new { person.FirstName, PetName = subpet?.Name ?? String.Empty };

    foreach (var v in query)
    {
        Console.WriteLine($"{v.FirstName+":",-15}{v.PetName}");
    }
}

// This code produces the following output:
//
// Magnus:        Daisy
// Terry:         Barley
// Terry:         Boots
// Terry:         Blue Moon
// Charlotte:     Whiskers
// Arlene:
nam
  • 21,967
  • 37
  • 158
  • 332
  • 4
    `subpet.Name` will throw if `subpet` is null. – Lee Jun 21 '17 at 16:02
  • 1
    `subpet?.Name ?? String.Empty` will evaluate to an empty string regardless if `subpet` is null or `subpet.Name` is null – Sir Rufo Jun 21 '17 at 16:06
  • @SirRufo My confusion was due to an error I was getting in one of my code as explained [here](https://stackoverflow.com/q/44681362/1232087). But I think `@JonSkeet` and `@hvd` have explained it at that post. – nam Jun 21 '17 at 16:33

2 Answers2

1

You are not misunderstanding. The programmer was testing subpet for null, because of DefaultIfEmpty()

In the expression

    subpet?.Name ?? String.Empty 
  • subpet can be null, in which case subpet?.Name is also null.
  • String.Empty can be shortened to ""

So to ensure a non-null string,

    subpet?.Name ?? ""
  • 1
    So... The OP *is* misunderstanding? –  Jun 21 '17 at 16:14
  • @buffjape. Thank you for explaining. But I did indeed misunderstand the proper uses of ? and ??. Please see my other SO question here that prompted me to post the above question. – nam Jun 21 '17 at 16:58
  • ok no problem. It seemed to me you were asking "Why use the `?.` operator here", instead of "What does the operator do?". –  Jun 22 '17 at 07:43
0

As mentioned by @Lee, subpet might be null. So, in calling subpet.Name throw an exception.Hence, ?? check the subpet is null or not, and ? back to the calling .Name property.

OmG
  • 18,337
  • 10
  • 57
  • 90