I constantly find myself writing similar code like the example below:
if (object["Object Name"] != null) {
if (object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
} else {
// Do Statement B
}
The problem here is that I much check if an object is null or not and then I can check it for it's actual contents.
"Statement B" is always the same and in my case is usually a SQL statement.
There must be a better way around this?
Thanks
Stephen
There is short circuiting in C# so you can do:
if(null != object && object.name == foo)
do A
else
do B
C# always evaluates the first expression in the conditional statement first and if that fails, it doesn't try anything else in that part of the statement.
To further this point, if you are going to have an expensive operation in the conditional statement along with one or more inexpensive operations, it's good to put it at the end if possible, so it will only check the expensive operation when it really needs to. So something like
if(trivial comparison && trivial comparison && REALLY EXPENSIVE OPERATION)
It will now only execute the expensive operation as a last resort.
Since C# does short circuiting, yes. Try this:
if (object["Object Name"] != null && object["Object Name"] == "Some Value")
{
// Do Statement A
}
else
{
// Do Statement B
}
I think rewriting the if-then-else to this will make it look nicer because of the single B-statement.
if ((object["Object Name"] != null) && (object["Object Name"] == "Some Value"))
{
// Do Statement A
}
else
{
// Do Statement B
}
Why the double check? Surely this would be sufficient:
if(object["Object Name"] == "Some Value") {
// Do statement A
} else {
// Do statement B
}
I sort of see what you're getting at with null checking, but the particular example you give doesn't require it.
EDIT: Now if you had written this instead:
if (object != null) {
if (object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
} else {
// Do Statement B
}
then the solution would be:
if(object != null && object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
DISCLAIMER: Not doing the general short circuit method.
Well, you could create a separate function to perform the lookup, especially if the query remains the same. So something like this: (pseudocode incoming)
private bool IsNullCheck(string objectName)
{
if (object["Object Name"] != null)
return false;
else
// statement B
}
if (!IsNullCheck("Object Name") && if(object["Object name"] == "Value") {
// stuffs
}
else
{
// Do Statement B
}
Or the like.
Related
Following is my null operator check
if (vessels?.Vessels?.Count == 0)
{ }
and object is below
private static readonly DataQueueItem _emptyVessel = new DataQueueItem()
{
VesselId = 1,
Vessels = null
};
It is going in else part but it should be in if block.
I am confused why it is happening.
Any help
Please change your code into =>
if ((vessels?.Vessels?.Count ?? 0) == 0)
{
// do something.
}
Explanation: As vessels can be null or vessels.Vessels can be null so, vessels?.Vessels?.Count will return (int?) type. At the same time, in the if condition if (vessels?.Vessels?.Count == 0) in the question, we are trying check a (int?)==(int). Which might not worked as you expected. We can not check null to a value. That's why I have added (vessels?.Vessels?.Count ?? 0). That part will return 0 if vessels?.Vessels?.Count is null. So, value will be checked with a value.
Do this instead:
if (vessels.Vessels == null)
{
// Code
}
The null keyword is a literal that represents a null reference, one that does not refer to any object. null is not the same as 0.
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
}
In IEnumerable.First function, how do I handle the case if there are no matches? Currently it just crashes...
MySPListItem firstItem = itemCollection.First(item => !item.isFolder);
if (firstItem != null)
{
TreeNode firstNode = GetNodeByListItem(my_treeview.Nodes, firstItem, ReportObject);
if (firstNode != null)
{
ReportObject.log("Selecting the first PDF");
selectPDF(my_treeview, firstNode, queryStr_param);
}
}
Error Message:
Sequence contains no matching element
Stacktrace: at System.Linq.Enumerable.First[TSource](IEnumerable1 source, Func2
predicate)
Ok, If it is exceptional for there to be no first,
try
{
var first = enumerable.First();
}
catch (InvalidOperationException)
{
// Oops, that was exceptional.
}
If you anticipate that there may be no first in some valid situations,
var first = enumerable.FirstOrDefault();
if (first == default(someType)) // null for reference types.
{
// Ok, I need to deal with that.
}
While you do a null check on the find, you don't in your predicate. The line
foundItem = itemCollection.Find(item => item.item.ID == PDFID);
Might throw an exception it item is null (have you inserted an null item in the collection?) or item.item is null (are you sure it's always there?).
You could do:
foundItem = itemCollection.Find(item => item != null &&
item.item != null &&
item.item.ID == PDFID);
More chatty, but you won't get a NullReferenceException.
Edit Well you changed your question. Now you do First. The First method will throw an exception if nothing is found. Use FirstOrDefault instead which will return null for a class or the default value for a struct.
foundItem = itemCollection.FirstOrDefault(item => item != null &&
item.item != null &&
item.item.ID == PDFID);
Replace First by FirstOrDefault :
MySPListItem firstItem = itemCollection.FirstOrDefault(item => !item.isFolder);
Quoted from the MSDN website you linked to:
The first element that matches the conditions defined by the specified predicate, if found; otherwise, the default value for type T.
This describes the return value. Hence, when no match is found, the default value for type T is returned, which means null for reference types, and things such as 0, false & co. for value types.
So in your calling code, simply check for this default value, and you're fine :-). What you can not do is just use the value that is being returned, as this e.g. might result in a NullReferenceException, if you are using a reference type.
Check if the result is null:
if (result == null)
{
Console.WriteLine("Not found");
}
There is a clear example demonstrating what to do if the item is found/not found here
It shouldn't throw an exception, you need to handle the case where it returns default(T). You might be getting a NullReferenceException because you're not handling the case where it returns null. For example:
IEnumerable<Cars> cars = GetCars();
Car car = cars.Find(c => c.Model == "Astra");
if(car != null)
{
// You found a car!
}
If you were doing the same for a struct, you'd check for it's default instead. Ints for example would be a 0:
int[] ints = new int[] { 1, 4, 7 };
int myInt = ints.Find(i => i > 5);
if(myInt != 0) // 0 is default(int)
{
// You found a number
}
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.