throught my app I've seen too many not equal null checks, which looks like this:
if (receivedRequest != null && receivedRequest.Status != null)
Is there cleaner way to write things like this?
Sure, since C# 6 you can use null propagation... something like this:
if (receivedRequest?.Status != null)
Check out this blog post with additional details...
It is possible to create un check method:
private bool CheckReceivedRequest()
{
return receivedRequest != null && receivedRequest.Status != null;
}
Used like that:
if ( CheckReceivedRequest() )
{
}
If receivedRequest.Status is not null, you don't need to check if receivedRequest is null.
if (receivedRequest.Status != null)
Related
I have a Unity App that is using c#.
I am getting a NullReferenceException: Object reference not set to an instance of an object on the line:
WeatherDict.Add(WeatherTypes[i].WeatherId, new List<WeatherMaps>());
for WeatherTypes[i].WeatherId
I am trying to check for null by using string.IsNullOrWhiteSpace as you can see.
for (int i = 0; i < WeatherTypes.Length; i++)
{
if (!string.IsNullOrWhiteSpace(WeatherTypes[i].WeatherId))
{
if (!WeatherDict.ContainsKey(WeatherTypes[i].WeatherId))
{
WeatherDict.Add(WeatherTypes[i].WeatherId, new List<WeatherMaps>());
}
}
}
I also tried this:
if (WeatherTypes[i].WeatherId != null || WeatherTypes[i].WeatherId != "")
But that still throws the same exception.
Is there another way to check for null?
Thanks!
If Weathertypes is null, the following code will cause a null reference exception:
if (WeatherTypes[i].WeatherId != null || WeatherTypes[i].WeatherId != "")
A safer approach looks like this.
if (WeatherTypes == null || WeatherTypes[i] == null)
You should learn to use the debugger. It will allow you to step through the code and look and see exactly what is null.
This is mainly a syntactic sugar/best-practice question.
Here is a code example in question:
if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
I understand that the safe navigation operator will continue execution if _instanceData is null, but in this case will the first boolean in the conditional be evaluated as expected? Is this going to successfully null check on both _instanceData and DataSourceType?
Another Example:
if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
In this case, it is possible that _instanceData is null, or it is not, but ObjInfo is null. Is it better practice to just old-fashioned null check both object and property, or will this get the job done as expected?
edit: The question is better described as:
Is if (obj?.prop != null) equivalent to
if (obj != null && obj.prop != null)
The first is equivalent to
if (_instanceData != null && _instanceData.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
The second is equivalent to
if (LockAcquired && _instanceData != null && _instanceData.ObjInfo != null) {// code}
So it will check if _instanceData is null, then check if _instanceData.DataSourceType is null, then the last condition. As you said, this is just syntactical sugar so you don't have to write two != null conditions. The IL code that results is exactly the same, so its a matter of preference whether or not to use the operator.
It does save a TON of space when accessing deeply nested properties, which is where its most useful
if(Parent != null)
{
if(Parent.Child != null)
{
if(Parent.Child.GrandChild != null)
{
Parent.Child.GrandChild.GreatGrandChild.name = "Parent IV";
}
}
}
becomes
Parent?.Child?.GrandChild?.GreatGrandChild.name = "Parent IV";
Saves a lot of space! Even if you collapsed all the ifs into one statement it still saves loads of keystrokes and screen noise.
I have the following line of code, which is giving me trouble of NPE
ServeUrl = ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment);
When I write this in the following way, I no longer get the NPE
if (ConfigurationManager.GetSection("Servers") != null && ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment) != null)
{
ServeUrl = ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment);
}
Somwhow, the above thing does not look good to my eyes. How can I write this in a better way?
I'd extract a temporary variable:
var section = (NameValueCollection)ConfigurationManager.GetSection("Servers");
if (section != null && section.Get(ment) != null)
{
...
}
Or even:
var section = (NameValueCollection)ConfigurationManager.GetSection("Servers");
if (section != null)
{
var url = section.Get(ment);
if (url != null)
{
ServeUrl = url;
}
}
What would you want to do if GetSection returned null though? Can you actually keep going?
!= means not equal to and == means equal to
If you can't use NULL you can use ""
Apply the condition with logic and then even after it is not getting what you want then:
condition will be false and you also used AND logical operator
I would have used this(FYI,i haven't tried this in compiler):
if (ConfigurationManager.GetSection("Servers")?.Get(ment) is NameValueCollection nvc)
{
ServeUrl = nvc;
}
So I have a Retrieve() function, which either gets me an object or a null (if that object is not found). I'm using an if statement with a boolean attribute of that object. It's set up like this.
if(Retrieve(index).IsForm == true) {}
The issue with this is that if it doesn't find an object, it'll throw a null reference exception. There are some ways around this, of course, but none that I find concise. There's a try...catch, but that seems pointless when I expect the error. I can check if the object is null first, if(Retrieve(index) != null), but that seems like adding needless nesting. Is there a clever way to handle this? I thought of using the null coalescing operator but it doesn't work in this situation.
You can either call the method twice:
if(Retrieve(index) != null && Retrieve(index).IsForm == true) { }
Or you can break the lines apart and store the result before the if:
var result = Retrieve(index);
if(result != null && result.IsForm == true) { }
You could write an IsForm function to do both operations for you:
bool IsForm(int index)
{
var result = Retrieve(index);
return result != null && result.IsForm;
}
if (IsForm(index))
...
The Null Object pattern would be helpful here. It keeps your calling code clean but does add an additional class.
class NullWhatever : Whatever
{
public NullWhatever() { IsForm = false; }
}
Whatever Retrieve(...)
{
...
return new NullWhatever(); // instead of null
}
You could make a Nullable_IsForm extension method. Then you could check for the null condition.
public static class RetrieveExtension
{
public static bool? Nullable_IsForm(this Retrieve retrieved)
{
if(retrieved == null)
{
return null;
}
else
{
return retrieved.IsForm;
}
}
}
Then in your code you'd check it against bool values
if(Retrieve(index).Nullable_IsForm == true)
{}
else if (Retrieve(index).Nullable_IsForm == false)
{}
else if (Retrieve(index).Nullable_IsForm == null )
{}
I don't think there is any more concise way to do it, no.
Shortest I can think of is:
if(Retrieve(index)!=null && Retrieve(index).IsForm == true) {}
but I don't like this because it calls Retrieve(index) multiple times. I'd go for
var foo = Retrieve(index);
if(foo!=null && foo.IsForm == true) {}
but that is obviously not doing anything clever or more concise. It is probably more efficeint than some of the alternatives.
You could put both conditions in the same if:
if(Retrieve(index)!= null && Retrieve(index).IsForm == true) {}
Thanks to short-circuit, if the null-check fails, rest of the expression is not evaluated.
I am facing inconsistent null value reference errors while I am trying to store my values from a serialized class object.
if ( item.current_location.city!=null )
{
var city = item.current_location.city.Select(i => i.ToString());
}
In the above code snippet, successful insertion takes place even if any index in item array has null values. But it throws exception in some cases,which I don't think can be distinguished in any manner from other cases( when the value is null)
item could be null as well
current_location could be null as well,
not only city.
This would help
if (item != null &&
item.current_location != null &&
item.current_location.city != null) {
...
}
EDIT:
Note: This code works, since c# implements a so-called shortcut-evaluation of Boolean expressions. If item should be null, the rest of the expression would not be evaluated. If item.current_location should be null, the last term would not be evaluated.
(I do not see any insertion in the code above.)
Starting with C#6.0 you can use the null propagation operator (?):
var city = item?.current_location?.city?.Select(i => i.ToString());
if (city != null) {
// use city ...
}
I can't give a definitive answer without seeing your dataset, but you're not checking for null values on the item object or the current_location object. I would suggest you start by changing your test to this:
if (null != item && null != item.current_location && null != item.current_location.city)
{
...
}