4

I may not have a good grasp of the ?? operator yet and ran into a design flaw I couldn't explain.

Compare the following two properties, the only difference being how there are initialized: the first explicitly initialized, while the second with the ?? operator (or am I doing it wrong here?).

If I run data init with both properties, the collection based on the first property comes up populated as expected, while the second one with the ?? operator never gets populated and comes up with 0 elements in the collection.

Surely something is wrong here in my assumption; what is the flaw here?

P.S. Please ignore the Set method which is to implement INotifyPropertyChanged in the base class and has no bearing on this issue (which is confined to the type of initialization).

// property version 1

private ObservableCollection<UserName> _userNameColl = new ObservableCollection<UserName>();
public ObservableCollection<UserName> UserNameColl
{
    get { return _userNameColl; }
    set { Set(ref _userNameColl, value); }
}

// property version 2

private ObservableCollection<UserName> _userNameColl;
public ObservableCollection<UserName> UserNameColl
{
    get { return _userNameColl ?? new ObservableCollection<UserName>(); }
    set { Set(ref _userNameColl, value); }
}

// a simple class for creating object collection

public class UserName
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

// a simple test populating the collection

for (int i = 0; i < 4; i++)
{
    // silly data init just for test

    UserNameColl.Add(new UserName()
    {
        Name = $"UserName No {i}",
        Age = 20 + i,
        Email = $"email{i}@local.lan"
    });
}
user2921851
  • 990
  • 12
  • 26
  • 2
    The second one never actually sets the value of the inner collection unless you set it manually, so unless you do it will return a new `ObservableCollection` instance every time you try to get it. – Abion47 Jan 16 '17 at 11:28
  • Aaaah! That explains it. – user2921851 Jan 16 '17 at 11:38

1 Answers1

5

The second one never initializes your field but always returns a new collection. Try this one instead:

public ObservableCollection<UserName> UserNameColl
{
    get { return _userNameColl ?? (_userNameColl = new ObservableCollection<UserName>()); }
    set { Set(ref _userNameColl, value); }
}
Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
  • The `??` operator has a confusing precedence, but you need to surround the assignment in parentheses before this will compile. – Abion47 Jan 16 '17 at 11:36
  • Of course! It's crystal clear when you know the answer and I can see it clearly!! Thank you. My FLAW is that I never set the value for _userNameColl and simply returning an instance. How silly is that! – user2921851 Jan 16 '17 at 11:41