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;
}
Related
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.
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)
So I know why I have a null reference exception in this case. My question is how I avoid it given this specific use.
I have a function interpreting JSON data like so:
public IActionResult SendLine([FromBody] User data) {
if (_assets.GetPropertyByName(data.Properties.PropertyName) == null) {
_assets.AddProperty(new Property {
IsToggle = data.Properties.IsToggle,
Order = data.Propertis.Order,
Type = data.Properties.Type,
PropertyName = data.Properties.PropertyName
});
}
_assets.AddRow(data);
return Json(data);
}
The problem is that the Property class can have null values like so:
{
properties: {
isToggle: false,
order: 0,
type: null,
propertyName: "Test"
},
....
}
So I get why it throws the exception that "properties" is null since it has a null value. However this is as intended. How do I check to see if the propertyName is null without it throwing that error?
EDIT:
I'm not sure how null conditionals would help this case. If I put it here
if (_assets.GetPropertyByName(data.Properties?.PropertyName) == null)
it will evaluate to null improperly.
Edit: Updated my answer after realizing this is probably closer to what you need (?):
If the if-clause is where your exception is thrown, just split it up a little more:
var propName = data?.Properties?.PropertyName;
var isPropNameFound = !string.IsNullOrEmpty(propName);
var prop = isPropNameFound ? _assets.GetPropertyByName(propName) : null;
if (isPropNameFound && (prop == null))
{
// Add new property if name was given, and it
// was not found to already have been added?
}
That should ensure propName is null if either data.Properties or data.Properties.PropertyName is null, and do so without throwing a NullReferenceException.
After that, it will run the logic in the if block only if propName had a value, and if _assets.GetPropertyByName(propName) did not return anything.
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)
{
...
}