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
Related
Is there a function in c# that can help to check if the statement is going to return error.
I am aware about try{} catch{} but we can't use it in condition checking. For example:
var opertionResult = SomeRestFunction.Trigger();
string ServerResponse = if(operationResult != null)
{
if(operationResult.Response != null)
{
operationResult.Response.ResponseText;
}
Else
{
"Null";
}
}
Else
{ "Null"; }
In the example above, I need to perform multiple checks to validate the operationResult object properties at multiple levels due to nested objects in it, to determine the final value I want to read and consume as server response value.
If we have some thing like IsError() function in Excel, we can simply try to read the final object property i.e. operationResult.Response.ResponseText; inside of that function and if any of the parent object is null and it has to throw an error it will return false and we can return the value from the else block as shown in the hypothetical example below:
var opertionResult = SomeRestFunction.Trigger();
string ServerResponse = IsError(operationResult.Response.ResponseText)? "Null": operationResult.Response.ResponseText;
So, do we have something like this in C#? Hope this makes sense?
If you're using c# 6 or newer version then you can use null-conditional & null-coalescing-operator operator like below.
Here you need to place ? to check if object is null or not. If object is null then it will not perform any further check and return null. And null-coalescing-operator (??) will be used to check if value is null then it will return value provided afer ??.
string ServerResponse = SomeRestFunction.Trigger()?.Response?.ResponseText ?? "Null";
Before you rush to think about the ?? null coalescing operator:
string result = myParent.objProperty.strProperty ?? "default string value if strObjProperty is null";
The problem here is when whether myParent or objProperty are null, then it will throw an exception before even reaching the evaluation of strProperty.
To avoid the following extra null checkings:
if (myParent != null)
{
if (objProperty!= null)
{
string result = myParent.objProperty.strProperty ?? "default string value if strObjProperty is null";
}
}
I generally use something like this:
string result = ((myParent ?? new ParentClass())
.objProperty ?? new ObjPropertyClass())
.strProperty ?? "default string value if strObjProperty is null";
So if the object is null then it creates a new one only to be able to access the property.
Which is not very clean.
I would like something like a '???' operator:
string result = (myParent.objProperty.strProperty) ??? "default string value if strObjProperty is null";
... which would survive whatever "null" from inside the parenthesis to return the default value instead.
Thanks for your tips.
What about the null propagation operator, which comes with C# 6?
string result = (myParent?.objProperty?.strProperty)
?? "default string value if strObjProperty is null";
It checks myParent, objProperty and strProperty for null and will assign the default value if any of them is null.
I have extended this feature by creating a extension method that checks for empty too:
string result = (myParent?.objProperty?.strProperty)
.IfNullOrEmpty("default string value if strObjProperty is null");
Where IfNullOrEmpty is just:
public static string IfNullOrEmpty(this string s, string defaultValue)
{
return !string.IsNullOrEmpty(s) ? s : defaultValue);
}
How can I check if any key from json object have null value
JsonObject itemObject = itemValue.GetObject();
string id = itemObject["id"].GetString() == null ? "" : itemObject["id"].GetString();
this is my code but app crashes on it if null value for key "id"
IJsonValue idValue = itemObject.GetNamedValue("id");
if ( idValue.ValueType == JsonValueType.Null)
{
// is Null
}
else if (idValue.ValueType == JsonValueType.String)
{
string id = idValue.GetString();
}
If you do this too much, consider adding extension methods.
To do the opposite use:
IJsonValue value = JsonValue.CreateNullValue();
Read here more about null values.
http://msdn.microsoft.com/en-us/library/ms173224.aspx
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
if itemObject["id"] is null then the method null.GetString() doesn't exist and you'll get the error specified (null object never has any methods/fields/properties).
string id = itemObject["id"] == null ? (string)null : itemObject["id"].GetString(); // (string)null is an alternative to "", both are valid null representations for a string, but you should use whichever is your preference consistently to avoid errors further down the line
the above avoids calling .GetString() until you've asserted that the ID isn't null (check here for more in-depth), if you're using C#6 you should be able to use the new shorthand:
string id = itemObject["id"]?.GetString();
Here is solution for the issue
string id = itemObject["id"].ValueType == JsonValueType.Null ? "" : itemObject["id"].GetString();
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)
{
...
}
I have:
An XML with some elements.
A sub-element that may or may not be defined inside this XML.
Need to extract the value of the sub-element when it does exist.
How do I get the value without throwing object-reference errors?
For example:
string sampleXML = "<Root><Tag1>tag1value</Tag1></Root>";
//Pass in <Tag2> and the code works:
//string sampleXML = "<Root><Tag1>tag1value</Tag1><Tag2>tag2Value</Tag2></Root>";
XDocument sampleDoc = XDocument.Parse(sampleXML);
//Below code is in another method, the 'sampleDoc' is passed in. I am hoping to change only this code
XElement sampleEl = sampleDoc.Root;
string tag1 = String.IsNullOrEmpty(sampleEl.Element("Tag1").Value) ? "" : sampleEl.Element("Tag1").Value;
//NullReferenceException:
//Object reference not set to an instance of an object.
string tag2 = String.IsNullOrEmpty(sampleEl.Element("Tag2").Value) ? "" : sampleEl.Element("Tag2").Value;
You can use the null-coalescing-operator for a shortcut:
string tag1= (string)sampleEl.Element("Tag1") ?? string.Empty;
This also uses the fact that LINQ to XML allows the cast operation to get the value of the element (in this case cast to string), but returns null if the element does not exist.
You'll need to check for null in order to prevent them. Given the repeated pattern you're using I would just factor this off into an extension method.
public static string GetElementValue(this XElement parent, string elementName) {
if (parent == null) {
return string.Empty;
}
var element = parent.Element(elementName);
if (element == null || element.Value == null) {
return string.Empty;
}
return element.Value;
}
Now your above code can be replaced with the following
string tag1 = sampleEl.GetElementValue("Tag1");
string tag2 = sampleEl.GetElementValue("Tag2");
The C# ternary operator is pretty good for this:
string tag2 = sampleEl.Element("Tag2") == null ? "" : sampleEl.Element("Tag2").Value;
First you should check if the document is null, remember you are accessing the .Value and this will throw a null reference exception so before you apply .value do a test:
if (sampleEl != null)
//now apply .value
Or ternary:
string tag2 = sampleEl.Element("Tag2") != null ? sampleEL.Element("Tag2").Value : String.Empty
Your code then becomes:
string sampleXML = "<Root><Tag1>tag1value</Tag1></Root>";
//Pass in <Tag2> and the code works:
//string sampleXML = "<Root><Tag1>tag1value</Tag1><Tag2>tag2Value</Tag2></Root>";
XDocument sampleDoc = XDocument.Parse(sampleXML);
//Below code is in another method, the 'sampleDoc' is passed in. I am hoping to change only this code
XElement sampleEl = sampleDoc.Root;
string tag1 = sampleEl.Element("Tag1") != null ? sampleEl.Element("Tag1").Value : String.Empty;
//NullReferenceException:
//Object reference not set to an instance of an object.
string tag2 = sampleEl.Element("Tag2") != null ? sampleEL.Element("Tag2").Value : String.Empty
string tag1 = sampleEl.Element("Tag1") != null ? sampleEl.Element("Tag1").Value : string.Empty;
I came up with this extension method. It requires you to specify the property to access as a lambda, and a default value to use if the actual value or anything up the chain is null:
public static TOut ValueOrDefault<TIn, TOut>(this TIn input, Func<TIn, TOut> projection, TOut defaultValue)
where TOut : class
{
try
{
return projection(input) ?? defaultValue;
}
catch (NullReferenceException)
{
return defaultValue;
}
catch (InvalidOperationException)
{
return defaultValue;
}
}
Usage:
var value = topObject.ValueOrDefault(x=>x.ChildObject.AnotherChild.ChildProperty, String.Empty);
value will be the empty string if topObject, ChildObject, AnotherChild, or ChildProperty are null. If all of those are valid references, the return will be whatever ChildProperty actually is (which could still be the empty string). The catch for the NullReferenceException handles references of child members of a null reference. For nullable types, InvalidOperationException is thrown when accessing the Value property of a null nullable type.
C# 6.0 allows us to make the expression shorter and simpler:
string uniqueIdentifier = myNode.Document?.Element("elem1")?.Element("elem2")?.Attribute("attribute1")?.Value;
Just for the fun of it, here's a solution using LINQ to XML which
requires only one statement and
does not need the ternary operator, so you don't need to specify the name of the tag twice:
string tag1 = sampleEl.Elements("Tag1").Select(x => x.Value).FirstOrDefault();
string tag2 = sampleEl.Elements("Tag2").Select(x => x.Value).FirstOrDefault();
Add ?? "" if you want the empty string instead of null if the tag does not exist.