What is the best way to deal with null values in Linq.
I have this code which retrieves the customer contacts from the db but if the contact details don't exist it creates a new instance
void SetProperty(int _CustomerID)
{
Contacts_GetResult Contact;
if (Global.VariableStore._Contact == null)
{
Contact = Cd.Contacts_Get(_CustomerID).SingleOrDefault();
if (Contact == null)
Contact = new Contacts_GetResult();
Global.VariableStore._Contact = Contact;
}
else
{
Contact = Global.VariableStore._Contact;
}
if (Contact != null)
{
HomeNumber.Value = Contact.HomeNumber.ToString();
MobileNumber.Value = Contact.MobileNumber.ToString();
WorkNumber.Value = Contact.WorkNumber.ToString();
EmailAddress.Value = Contact.EmailAddress.ToString();
}
When it create the new contacts all the values are null which makes the below code fail as the value is null
HomeNumber.Value = Contact.HomeNumber.ToString();
I currently use:
if (Contact.HomeNumber != null)
HomeNumber.Value = Contact.HomeNumber.ToString();
Is there an easier way?
There is a number of ways, all of which include checking for null one way or the other:
if (Contact.HomeNumber != null)
HomeNumber.Value = Contact.HomeNumber.ToString();
HomeNumber.Value = (Contact.HomeNumber ?? string.Empty).ToString();
HomeNumber.Value = Contact.HomeNumber != null
? Contact.HomeNumber.ToString()
: string.Empty;
There is a slight difference in that the last two samples will substitute the null value with an empty string. In the case of the ?? operator, there is nothing much to do about that; that whole code construct is about making sure that the value is not null before operating on it. That code is the most compact of them, but comes with the downside of unnecessary calls to ToString when HomeNumber is null.
In the case of the ?: operator, that sample can easily be altered to return null instead of an empty string:
HomeNumber.Value = Contact.HomeNumber != null
? Contact.HomeNumber.ToString()
: null;
I use the following extension method to (somewhat) simplify guarding against null instances:
public static V ValueOrDefaultIfNull<T, V>(this T #this, Func<T, V> #value, V #default)
{
return #this != null ? #value(#this) : #default;
}
So now I can make calls like this:
HomeNumber.Value = Contact.ValueOrDefaultIfNull(x => x.HomeNumber.ToString(), "N/A");
Related
I'm just looping and appending my properties to a big string:
output.Append(property.GetValue(this).ToString()));
When app breaks in that moment property represent a ProductNumber which is a string, value of this is Product object which has value of ProductNumber = null, so I've tried something like this:
output.Append(property.GetValue(this)?.ToString()));
But anyway it breaks..
How could I improve this code to avoid breaking there?
Thanks
Cheers
It seems that output.Append complains on null values. There are 2 possible sources of pesky nulls here:
property.GetValue(this) returns null and thus ?. in ?.ToString() propagates null
ToString() itself returns null (hardly a case, but still possible)
We can solve both possibilities with ?? operator: let's return an empty string whatever the source of null is:
property.GetValue(this)?.ToString() ?? ""
Final code is
output.Append(property.GetValue(this)?.ToString() ?? "");
This code:
output.Append(property.GetValue(this)?.ToString()));
Is the same as:
object propValue = property.GetValue(this);
string propString = null;
if (propValue != null)
{
propString = propValue.ToString();
}
output.Append(propString); // propString can be null
This can be simplyfied like so:
string propString = property.GetValue(this)?.ToString(); // This performs a ToString if property.GetValue() is not null, otherwise propString will be null as well
output.Append(propValue); // propValue can be null
If you want to prevent calling Append with a null value you can do:
string propString = property.GetValue(this)?.ToString(); // This performs a ToString if property.GetValue() is not null, otherwise propString will be null as well
if (propString == null)
{
propString = string.Empty;
}
output.Append(propValue); // propString is not null
This can be simplified with the null-coalescing operator:
string propString = property.GetValue(this)?.ToString() ?? string.Empty
output.Append(propValue); // propString is not null
This may sound simple, but i really want to find a better way of writing the below code,
if (Master.SerialNo1 != null)
{
result.ChipId = Master.SerialNo1;
}
if (Master.SerialNo2 != null)
{
result.ChipId = Master.SerialNo2;
}
if (Master.SerialNo3 != null)
{
result.ChipId = Master.SerialNo3;
}
if (Master.SerialNo4 != null)
{
result.ChipId = Master.SerialNo4;
}
Try using ?? operator:
result.ChipId = Master.SerialNo1 ?? Master.SerialNo2 ?? Master.SerialNo3 ?? Master.SerialNo4 ?? null;
Of course, instead of null you can use any default value.
Assuming the types of ChipId and SerialNo are the same, how about:
result.ChipId = Master.SerialNo1 ?? Master.SerialNo2 ?? Master.SerialNo3 ?? Master.SerialNo4;
This will assign to ChipId the first non-null reference in the order they occur on the right hand side.
This might be more readable formatted over multiple lines:
result.ChipId =
Master.SerialNo1
?? Master.SerialNo2
?? Master.SerialNo3
?? Master.SerialNo4;
?? is known as the "null coalescing operator".
hello to all i have this method
public void insertXmlNode(string XmlParentNodeName, List<string> XmlNodeName, List<string> XmlNodeValue, List<string> XmlAttributeName, List<string> XmlAttributeValue)
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load(_connection);
XmlNode xparent = xdoc.SelectSingleNode("//" + XmlParentNodeName);
if (xparent == null)
{
xparent = xdoc.CreateNode(XmlNodeType.Element, XmlParentNodeName, null);
xdoc.DocumentElement.AppendChild(xparent);
}
for (int i = 0; i <= XmlNodeName.Count; i++)
{
XmlNode xnode = xdoc.CreateNode(XmlNodeType.Element, XmlNodeName[i], null);
xnode.InnerText = XmlNodeValue[i];
if (!string.IsNullOrEmpty(XmlAttributeName.ToString()))
{
XmlAttribute xattribute = xdoc.CreateAttribute(XmlAttributeName[i]);
xattribute.Value = XmlAttributeValue[i];
xnode.Attributes.Append(xattribute);
}
xparent.AppendChild(xnode);
}
xdoc.Save(_connection);
}
and i call this like below:
_db.insertXmlNode("Orders", _orderName, _orderValue, null, null);
"_db is a class instanc and _orderName & _orderValue has list string "
i wanna if XmlAttributeName not null add attribute to xml node but i
get this error
value can't be null
how i can check if XmlAttributeName not null do somthing?
Instead of doing the check this way, as you said in comment :
if (XmlAttributeName != null ||
XmlAttributeName.All(x => string.IsNullOrWhiteSpace(x)))
{
.......
}
Try to do it this way :
if (XmlAttributeName != null &&
XmlAttributeName.All(x => !string.IsNullOrWhiteSpace(x)))
{
.......
}
With && operator 2nd condition will only be checked if the 1st condition met. And code execution will enter if block, only if XmlAttributeis not null and all attributes in the list is not null or empty string.
private bool HasInvalidValues(IEnumerable<string> enumerable)
{
return enumerable == null || enumerable.Any(string.IsNullOrWhiteSpace);
}
The correct way to check for nullity is if(XmlAttributeName != null). This kind of check is ubiquitous for reference types; even Nullable<T> overrides the equality operator to be a more convenient way of expressing nullable.HasValue when checking for nullity.
If you do if(!XmlAttributeName.Equals(null)) then you will get a NullReferenceException if data == null. Which is kind of comical since avoiding this exception was the goal in the first place.
if (XmlAttributeName != null &&
XmlAttributeName.All(x => !string.IsNullOrWhiteSpace(x)))
{
// do here
}
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;
}
I wondered if anybody can come up with a shortened version for this code:
MyObject theObject = ObjectCollection.GrabAnObject();
if (theObject == null) return String.Empty;
else return theObject.myProperty;
Thank you!
MyObject theObject = ObjectCollection.GrabAnObject();
return theObject == null ? String.Empty : theObject.myProperty;
In c# 3.0 (framework 3.5) you can write:
return (ObjectCollection.GrabAnObject() ?? new MyObject(){ myProperty = ""} ).myProperty;
but I will write something more readable like:
return new MyObject(ObjectCollection.GrabAnObject())
and set the property accordly in the constructor
EDIT:
My memory make me a joke:
?? is not a c# 3.0 feature, but a 2.0 one ;)
MSDN link
That code is fine, although I'd recommend the following to improve readability (and I'm not the only one).
MyObject theObject = ObjectCollection.GrabAnObject();
if (theObject != null)
return theObject.myProperty;
return string.Empty;
var theObject = ObjectCollection.GrabAnObject();
return theObject != null ? theObject.myProperty : String.Empty;
// if you want an String.Empty always to be returned, also when the property is null
return theObject != null ? theObject.myProperty ?? String.Empty : String.Empty;
Use the ?: operator:
MyObject theObject = ObjectCollection.GrabAnObject();
return (theObject == null) ? String.Empty : theObject.myProperty;
Sure, you can use the ? operator.
MyObject theObject = ObjectCollection.GrabAnObject();
return (theObject == null) ? String.Empty : theObject.myProperty;
I don't believe you can get this on one line without calling ObjectCollection.GrabAnObject() twice.