re: No more NullReferenceException for Lists in C# VIEW POST

TOP OF THREAD FULL DISCUSSION
re: "There is no wrong or right ideas, especially when it's working" As I had to tell students back in university "it's working" is the absolute minim...
 

When you are working with a list as a property of a class , and the class is already instantiated , what is the point of the null reference exception when you explicitly want to add an item to it ?

As I said, you're trying to solve the local problem without looking at the bigger picture.

The first question you should ask yourself is "Why is this list property ever null?" Does null have a specific meaning that's different from an empty list? That's a valid reason, but that's very rarely the case. And if it is, then you have to treat it differently anyhow so that extension method wouldn't make sense either.

But in practice, in almost all situations the best approach is to simply initialize the property with an empty list during construction. This makes code the much simpler to reason about and makes such hacks completely unnecessary.

The question is not the difference between null and empty , there is no doubt that both are necessary , but why there is an extra operation in adding an item to a for instance list ,in my opinion all the collections should be auto initialize themselves on adding new item to them , off course i 'm not speaking about get Operation , but when you want to add an item to a list most definitely you want it to be initialized , and in my opinion this should be taken care by the compiler during the compiler code generation , best practices were developed gradually and the process is ongoing :)

But there is an important difference between null and empty and your solution peppers over a simple programmer error while hiding that difference.

C# is almost 20 years old by now and it and the whole world is moving towards non-nullability by default. C# 8 makes this easier than ever before.

There simply is no reason to write your code instead of simply doing

public sealed class Foo 
{
    public ICollection<int> SomeInts { get; } = new List<int>(); // there we go, never going to be null.
}

Why should the compiler special case lists? What about Dictionaries? Old StringCollections from the time before generics? What about stringbuilders or custom classes that implement ICollection? What if they don't have a no argument constructor?

A whole lot of complicated questions to answer for a problem for which best practices have existed for decades: Initialize your classes in such a way that all its properties have valid values.

Your solution about initializing at object construction contradicting with your own stated argument regarding the difference between null and empty if you initialize the object at the construction you will loose the chance of determining whether the collection ever been used or not, also can cause overhead in some cases in grained memory management, all i'm saying is adding to a list and initializing it when it's null should happen at once and the developer should not be woried about the initializing it when they try to add to it , in c# 8 still you may define a nullable list, therefore the question will remain intact

Read again: What I said is that in some rare situations it makes sense to distinguish between empty and null collections. In almost all situations it does not.

And sure there are incredibly rare situations where the memory pressure of unnecessarily initialising a list will cause performance problems, but the 101 of performance is to first write clean, simple code and only when you actually have a problem profile and start optimising.

I take any bet that you've never come across a situation in your professional development life where that was actually a problem (and adding a branch to every single add of a list is quite awful from a performance point of view too).

And yes in C# 8 you can still define a nullable list, but best practice tells you that you should avoid nullability as much as possible.

But I mean if the fact that pretty much every single comment is negative to this idea and that it goes against best practices in modern C# and nobody else is doing this despite extension methods being around for years (I mean the whole "use extension method to be able to use instance methods on possibly null values" has been done to death - usually for things such as assertions, this is not novel in itself) convinces you this might not be the best idea, I doubt me going on about this will make a difference.

I'm not claiming that the approach of this article is the best solution or following the best practices , just a demonstration of a prototype of a possible better approach. About writing simple and profiling , it depends on the application , simplicity and clean code are guidelines , not an approach , it always depends , you don't need to bet ,what i have faced in my career or you have is not relevant , the approach should be generic , can you think of any condition which you are adding an item to a collection but Don't want to initialize it ?
Because i don't think there is , therefore i believe the first addition should handle the initialization

I feel like you're being intentionally obtuse about this when everyone else has provided great arguments in favor of always-initializing collections.

To play your game, here's an example:


class LibraryVisitor {
  private List<Book> CheckedOutBooks { get; set; }
  private string MemberNumber { get; set; }

  public void CheckOut(Book book) {
    CheckedOutBooks.Add(book);
  }

  public void Register(memberNumber) {
    MemberNumber = memberNumber;
    CheckedOut = new List<Book>();
  }
}

This is obviously shit code (arguably no worse than your examples), but the premise is I shouldn't be able to check out a book until I've registered.

A reasonable fix to this code would be:


class LibraryVisitor {
  private List<Book> CheckedOutBooks { get; } = new List<Book>();
  private string MemberNumber { get; }

  public void CheckOut(Book book) {
    if (MemberNumber == null) {
      throw new NotRegisteredException();
    }

    CheckedOutBooks.Add(book);
  }

  public void Register(memberNumber) {
    MemberNumber = memberNumber;
  }
}

When you don't get , you don't get it.
let me demistify once more.
The conventional methods which any junior developer should be aware are crystal clear . The issue is why when you are trying to add to a list which is a member of a class and you already instantiated the class should throw an exception ?
It should instanciate the list object on the first add itself.

code of conduct - report abuse