From the course: Advanced C#: Functional Programming Patterns

Use an immutable argument

The real issue with the previous example is that the List<T> is a mutable type. So I was able and when I passed in as a parameter, I was able to add items to the list, remove items to list. I could find an individual item on the list and change the value of it at that location. So that's the danger. If I'm passing in the parameter and I'm not careful, I could mutate the state of the internal state of that list. The way we get around this is to try to make our arguments immutable, and I'll talk more about immutability in the next chapter. I'd like you to know, though, that there are a number of collection classes in .NET that are thread-safe. There's a concurrent collections, and there's also the immutable types, the immutable lists. And so I thought I would show you a quick example of using the ImmutableList<T>. It looks the same when you declare it here on line 29. However, there's not a standard constructor. If you're used to working with the List<T> constructor, it won't work that way. So if you want just an empty list, you can call EnumerableList<int>. Empty and that will return an empty list. It's initialized, but there's no items in it. If you want to add items, instead of using a constructor, instead you use this factory method called create. So I'm saying create an immutable list with these four values. Now once line 31 has run, you can't change the state of that list. So now when I call AddNumbersToList(), it's safe. Or is it? Let's check it out. It's coming in here as a parameter. And I am doing the same code that we showed you in the previous video where I'm calling inputList.Add(2), inputList.Add(4). But let's see what add does. Add returns an immutable list of int. So when you call this, it's going to return a new list with five items in it. It's not going to affect this parameter. Let's verify that. I'll put a breakpoint here. Look at inputList. That's the inbound parameter. It had four items in it, when I call this method, it still has four items in it. So what happened on line 42? Well, it created the new immutable list of integers, but I didn't do anything with it. It basically discarded it. So that means my code is not working as I expect. I'm not ending up with a list that has six items at the end of this. No, but I don't have a side effect from calling this method because of the type. Now, the way to fix this, of course, is if I really want to add the numbers to the list, what I should do is return instead of a void here, I should return an ImmutableList<T>. So I return that. And then down here, let's just add one item. So I'll comment this out. Return this. So this will add an item to the list and then return the ImmutableList<int> with five items in it. And of course, I would now also need to do something sensible with my code up here. But I think you get the idea. By using this immutable list, we are always guaranteed that we won't inadvertently change the data. We still have to be good developers and understand that when we are attempting to modify, we don't end up with code that doesn't work the way we expect. But again, we don't have the side effect of mutating the state.

Contents