📜 ⬆️ ⬇️

?.: when properties in C # can be null

The more I write in C # 6, the more convinced I am how much the operator is ?. ( null coalescing operator ) helps to write clean, simple and clear code. Today I will show 4 situations in which he can be very useful.

Large nesting

Consider the following problem. There is a supplier, the supplier has a contact person, the contact person has a home address, the home address has the first line, and we want to find this very first line. Previously, I would have to write code with a high level of nesting, checking for null each value in the chain:

 var location = default(string); if (vendor != null) { if (vendor.ContactPerson != null) { if (vendor.ContactPerson.HomeAddress != null) { location = vendor.ContactPerson.HomeAddress.LineOne; } } } 

But now we have C # 6, with it the code can be given in a much more readable form:
')
 var location = vendor?.ContactPerson?.HomeAddress?.LineOne; 

Operator ?. makes it so that as soon as one of the properties of the chain is null , no further evaluation of the expression will be performed. Let's see some more examples.

INotifyPropertyChanged and related APIs

We all have seen classes that implement the INotifyPropertyChanged interface. In them you can find the following properties:

 public string Name { get { return name; } set { if (name != value) { name = value; PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } private string name; 

Noticed something was wrong? The code will fail if the INotifyPropertyChanged.PropertyChanged event INotifyPropertyChanged.PropertyChanged no subscribers. In this situation, many developers begin to write like this:

 public string Name { get { return name; } set { if (name != value) { name = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Name")); } } } private string name; 

Okay, it's a bit better. It is possible that this code will work in most cases. However, nobody canceled the race condition: if the subscriber unsubscribes from the event at the moment after we check PropertyChanged != null , but before PropertyChanged called, the program will still crash. And it will happen at the most inopportune moment in a few months after installing the application on the client. Let's fix this annoying problem: save the reference to PropertyChnaged in a local handler variable, check it for null , and then work with this local variable, and not with the PropertyChnaged public event:

 public string Name { get { return name; } set { if (name != value) { name = value; var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs("Name")); } } } private string name; 

Oh, the code has become a lot, it is difficult to remember all this and call PropertyChanged correctly every time. In a large program, someone somewhere will surely forget to do all the checks. What to do? C # 6 will save us! All our checks are easy to replace with the operator ?. and calling the invoke method:

 public string Name { get { return name; } set { if (name != value) { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); } } } private string name; 

The code is shorter, easier to read, all necessary checks are performed, there are no problems.

Resource management

And now this situation: there is an object of some type, the description of which we know. It is necessary to understand that this object can implement interfaces about which the type is not known. This is usually not a problem, but what if the object implements IDisposable . Imagine the evil genius who decided to retire one of his minions. The corresponding code will look like this:

 public void RetireHenchman() { var disposableMinion = Minion as IDisposable; if (disposableMinion != null) disposableMinion.Dispose(); Minion = null; } 

Operator ?. again will help improve the quality of our code:

 public void RetireHenchman() { (Minion as IDisposable)?.Dispose(); Minion = null; } 

LINQ queries

I found two cases where the operator ?. may be useful in LINQ queries. Case one: I want to create a query using the SingleOrDefault() method, and the resulting object (if it exists) access some property. There is nothing easier:

 var created = members.SingleOrDefault(e => e.name == "dateCreated")?.content; 

Case two: I want to return null if the source sequence is null :

 members?.Select(m => (XElement)XmlValue.MakeValue(m)) 

Conclusion

Adding the considered operator made me realize how often null checks are found and how shorter and more readable the code can be made using the new syntax. Thanks ?. I began to write code differently. I can’t wait for the final release of C # 6 to be released so that I can give my customers a new version of the source code.

Source: https://habr.com/ru/post/252099/


All Articles