7

So insteed of writing:

if (obj.Collection == null)
    obj.Collection = new Collection();
obj.Collection.Add(something);

I thought of writing:

obj.Collection = obj.Collection ?? new Collection;
obj.Collection.Add(something);

It kind of feels wrong, especially this part "obj.Collection = obj.Collection..."

What do you guys think ?

Regards,

Danko Durbić
  • 7,077
  • 5
  • 34
  • 39
Calin
  • 6,661
  • 7
  • 49
  • 80

4 Answers4

15

If I had to choose between these two blocks of code, I would use the former. It's more readable and it's a common pattern. ?? is useful in scenarios where you need to default a value (e.g., DateTime date = nullableDateTimeInstance ?? defaultDate;).

But frankly, I'd try to not end up in situation where I want to add to collection and it's possible that the collection is null. Instead, I'd make sure that the collection is initialized in the constructor or whatever the case may be.

jason
  • 236,483
  • 35
  • 423
  • 525
  • 1
    Or even do the initialization in the getter of property! – Jahan Zinedine Jan 23 '11 at 19:26
  • You are very right, but if Collection is a virtual member in a class (let's say a nhibernate entity class). Then you will end up with a warning "Virtual member call in constructor". I prefer the above then this warning. – Calin Jan 23 '11 at 19:35
  • @Calin: Please give a very simple block of code that reproduces the warning you are describing because I think done properly that should not be the case. – jason Jan 23 '11 at 19:39
3

Do you mean:

if (obj.Collection == null)
   {
      obj.Collection = new Collection();
   }
obj.Collection.Add(something);

If so, you can rewrite it as

(obj.Collection = (obj.Collection ?? new Collection())).Add(something);
tenor
  • 1,095
  • 6
  • 8
0

The code will emit an unnecessary assignment (of obj.Collection to itself) if obj.Collection is not null, but other than that it is equivalent to the original.

Looks fine to me provided you don't use it in time critical sections. Anyway it's possible the compiler can optimise the assignment away, but I don't know if it would or not.

Perhaps it just feels wrong because the original code is such a common and simple pattern that it feels wrong to change it.

James Gaunt
  • 14,631
  • 2
  • 39
  • 57
0

I'd say it also depends on what the setter of the Collection property does. Consider this:

public Collection Collection
{
    get { return _collection; }
    set
    {
        _collection = value;
        Thread.Sleep( 1000 ); // or some expensive real work
    }
}

In this case, the assignment obj.Collection = obj.Collection ?? new Collection() would be really costly.

However, if you need to create a collection "on demand", it's common to use a similar pattern in the property getter, like this:

public Collection Collection
{
    get { return _collection ?? ( _collection = new Collection() ); } 
}
Danko Durbić
  • 7,077
  • 5
  • 34
  • 39