C# Foreach-loop giving Null-error - c#

I'm writing a bit of code, and there is a part that gives me hassles.
I'm having the following structure in my code:
foreach (Node node in nodes)
{
try
{
bool n = node.previous == null;
}
catch (Exception e)
{
StreamWriter s = new StreamWriter("error.txt");
s.WriteLine(e.Message);
s.WriteLine("-----------");
s.Close();
}
}
In here Node is a custom type, the node.prev variable is also a custom type (Location). Running this gives the following error-log:
Object reference not set to an instance of an object.
-----------
I'm 100% sure that node isn't null (which should be made impossible by foreach = Not true, sorry!). Also, as you can see in the following listing, the Node.previous is set to null at declaration:
public class Node
{
public Location previous = null;
public Location location;
public int distance;
...
...
}
I have no idea how I can fix these exeptions occuring, and I'm kind of at the end of having any ideas on how to solve this. Can anybody help me with this?
Note that these are all not the final code, but I sifted the parts that didn't matter!
Thanks in advance,
Delpee
EDIT: Ricovox helped me to the solution with this answer, thanks a lot!

So I'm posting another answer in response to your comment:
"I have checked for node being null, it isn't, at any point."
If that IS true, there here are some other options;
Take a look at the node.previous class/struct definition. It COULD implement a CUSTOM == operator that throws an error when compared to null. As an example, think about the Nullable<T> type. It has an overloaded == operator that returns true if the HasValue property is false (obviously, since it is a struct it isn't truly null, but overloading the operator gives the desired behavior.) To fix this, you could test object.ReferenceEquals(node.previous, null) which wouldn't be overloaded. If you have access to change the node.previous definition, perhaps you can find out why the overloaded operator throws an exception when compared to null (which it obviously shouldn't)
nodes could be null, in which case it is the foreach statement that is throwing the error. Test nodes == null before the foreach.
---------------Edit---------------
As Jeppe pointed out, my analogy with Nullable<T> (in option #1, above) could be misleading (in fact it did confuse the discussion, although the point itself was correct). In order to better illustrate the idea of overriding the == operator, I've posted an example below that demonstrates the Container type. This type is a struct, so it can never be null itself, but it contains a single Value object.
(The point of this struct is that you can work with any Container object without worrying whether or not it is null, even though the contained Value object might be null). The main thing to note is that when a Container is compared with == to null, the result will be true if Value is null, which would NOT be true if the == operator weren't overridden (because a struct can never be null).
public struct Container {
public object Value { get; set; }
public bool IsNull { get { return Value == null; } }
public static bool operator ==(Container x, object y) { return x.Equals(y); }
public static bool operator !=(Container x, object y) { return !x.Equals(y); }
public override bool Equals(object obj) {
if (obj is Container)
return Value == ((Container)obj).Value;
return Value == obj;
}
public override int GetHashCode() { return Value == null ? 0 : Value.GetHashCode(); }
}
////---------Test----------
var x = new Container { Value = null };
var y = new Container { Value = "hi" };
var z = new Container { Value = null };
Print(x == null); //true
Print(x == y); //false
Print(x == z); //true
And just in case you are wondering how overriding == would affect a class, I've written another example below that demonstrates a Box class. It's similar to the Container struct, except that we have to deal with the case in which the Box object is null itself. Note that in this case, there is another surprising result of overriding ==. Two reference types can be equal (==) to each other, even if they reference different objects, as long as they have equal Value properties.
public class Box {
public static bool ItemsEqual(object x, object y) {
object xval, yval;
xval = x is Box ? (x as Box).Value : x;
yval = y is Box ? (y as Box).Value : y;
return xval == yval;
}
public object Value { get; set; }
public bool IsNull { get { return Value == null; } }
public static bool operator ==(Box x, object y) { return ItemsEqual(x, y); }
public static bool operator !=(Box x, object y) { return !ItemsEqual(x, y); }
public override bool Equals(object obj) { return ItemsEqual(this, obj); }
public override int GetHashCode() { return Value == null ? 0 : Value.GetHashCode(); }
}
////---------Test----------
object n = null;
Box w = null;
Box x = new Box { Value = null };
Box y = new Box { Value = "hi" };
Box z = new Box { Value = "hi" };
Print(w == null); //true (uses overridden '==' because w is defined as a Box)
Print(w == n); //true
Print(x == w); //true
Print(x == null); //true
Print(x == n); //true
Print(w == y); //false
Print(x == y); //false
Print(y == z); //true (actual ref's differ, but values are ==)

The most likely problem is that node is null!. There is nothing about the foreach statement that would prevent node from being null, because in general an IEnumerable object (e.g. a list or collection) CAN contain null as a valid item.
No error would be thrown if previous is null (unless the node.prev class/struct overrides the == operator).
As others have mentioned, put in a test like this to verify:
foreach (Node node in nodes)
{
bool n;
try
{
if (node == null)
{
n = true; //do something to deal with a null node
}
else
{
n = node.previous == null;
}
}
catch (Exception e)
{
StreamWriter s = new StreamWriter("error.txt");
s.WriteLine(e.Message);
s.WriteLine("-----------");
s.Close();
}
}

If nodes were null the exception would occur before the loop, and the exception wouldn't be caught.
Since the previous member is a simple field, the only possibility I see is that one of the node members of your nodes collection is null. You can do this:
foreach (Node node in nodes)
{
if (node == null)
throw new Exception("I told you so");
}
EDIT: OK, it turned out there was one possibility I didn't see, and that was a broken overload of the == operator. To make sure you call the usual overload, say:
foreach (Node node in nodes)
{
bool n = (object)(node.previous) == (object)null;
}
(actually it will suffice to cast just one side of the == operator to object), or equivalently use ReferenceEquals:
foreach (Node node in nodes)
{
bool n = object.ReferenceEquals(node.previous, null);
}
But you must fix the wrong implementation of the == overload.
If you had posted the stack trace of the exception in your original question, it would have been clear to most users here on SO that the exception came from a call to your == overload. So next time, inspect your stack trace.

set a breakpoint at your line that starts with bool and verify that node is not null and that nodes is not null. My guess is that either nodes is null, or else it contains a null value if it's not a type-safe list.

There's nothing that ensures that node is not null, since Node is not a value type. Mind giving more details?

I'm 100% sure that node isn't null
But I'm 100% sure that an element in nodes is null! try this:
foreach (Node node in nodes)
{
try
{
if(null == node) throw new Exception("This is not expected!");
bool n = node.previous == null;
}
catch (Exception e)
{
if(File.Exists("error.txt")) File.Delete("error.txt");
using(StreamWriter s = new StreamWriter("error.txt")){
s.WriteLine(e.Message);
s.WriteLine("-----------");
s.Close();}
}
}

Related

Binary trees FindParent method doesn't seem to work

Here is my BNode class
class BNode
{
public int number;
public BNode left;
public BNode right;
public BNode(int number)
{
this.number = number;
}
}
And here is my implementation of FindParent method in BTree class
public BNode FindParent(BNode BNode, BNode searchNode)
{
if (searchNode.left == BNode || searchNode.right == BNode)
{
return searchNode;
}
if (searchNode.left != null)
{
return (FindParent(BNode, searchNode.left));
}
if (searchNode.right != null)
{
return (FindParent(BNode, searchNode.right));
}
return null;
}
Here is how i call it
BNode bnodeFound = btree.Find(18);
BNode bparent = btree.FindParent(bnodeFound, btree.rootNode);
It returns null always, except when the number is the first root from the trees root. What i also found trough debugging is that it goes to the left-most root, checks that it has no right root and then returns null. Have tried to figure out this, but to no success. I use similiar way to find a number in the tree, and that works for finding 18.
When you call FindParent() recursively each time for the left node (when it is not null), you are returning it directly which means the FindParent() for the right node will never be called.
// Assume we run this for the root node
if (searchNode.left != null)
{
// If left node is not null, then it tries to find in left subtree only
// Since it returns directly, whether found or not-found it WILL NOT
// search in right sub-tree
return (FindParent(BNode, searchNode.left));
}
// Unreachable code if left is not NULL
if (searchNode.right != null)
{
return (FindParent(BNode, searchNode.right));
}
To fix you can remove the return statement and instead check if it is still not found.
if (searchNode.left != null)
{
var found = (FindParent(BNode, searchNode.left));
// Return if found, else continue to check in right
if (found != null) return found;
}
// Checks in right sub-tree if not found in left subtree
if (searchNode.right != null)
{
// While checking in right sub-tree, then return irrespective of whether
// it was found or not found, since there aren't any more places to check
return (FindParent(BNode, searchNode.right));
}

check if list is null in c# method

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
}

How to handle no matches case in List.First in c#?

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
}

possible null assignment in Dictionary Contains Key

Getting a warning on "!redirectsDictionary.ContainsKey(autoRedirect.Key)"
asp.net possible null assignment to entity marked with "notnull" attribute.
Just wondering what that's about ?
private static readonly Dictionary<string, Redirect> AutoRedirectsDictionary = new Dictionary<string, Redirect>();
foreach (var r in db.SelectItems("fast:/sitecore/content/Redirects Root//*[##templatename='Auto Redirect']"))
{
GenerateRedirects(Context.Database.GetItem(r.Fields["Root Node"].Value), r["URL Prefix"]);
foreach (var autoRedirect in AutoRedirectsDictionary)
{
if (!string.IsNullOrEmpty(autoRedirect.Key) & !redirectsDictionary.ContainsKey(autoRedirect.Key))
{
//Add to dictionary
redirectsDictionary.Add(autoRedirect.Key, autoRedirect.Value);
}
}
}
public static void GenerateRedirects(Item redirectFolder, string urlPrefix)
{
if (redirectFolder == null)
return;
var childList = redirectFolder.GetChildren();
foreach (Item child in childList)
{
if (Utilities.HasFieldValue(child, FieldToFind))
{
var shortcutUrl = urlPrefix + child.Fields[FieldToFind].Value.ToLower();
if (!string.IsNullOrEmpty(shortcutUrl) && !AutoRedirectsDictionary.ContainsKey(shortcutUrl))
{
AutoRedirectsDictionary.Add(shortcutUrl,
new Redirect(String.Empty, child, true));
}
}
else
{
GenerateRedirects(child, urlPrefix);
}
}
}
It might have to do with your use of the single & operator. A single & will not use short-circuiting to bypass a statement but will instead choose the path to execute after all expressions have been evaluated. So even though you're checking !string.IsNullOrEmpty(autoRedirect.Key) prior to the ContainsKey call, both expressions will be evaluated first and then the path of execution will be decided.
Edited as I realized I didn't truly answer your specific question (and you may already know this) but !redirectsDictionary.ContainsKey(autoRedirect.Key) will throw an exception if the key is null. Since the datatype for the key is a string there is a possibility it will throw an exception if it is null, hence the warning.

Is there a clever way to handle this null object reference?

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.

Categories

Resources