Null Reference Exception despite checking for Null - nullreferenceexception

I'm reading from an XML file with C# that has a dynamically generated number of nodes named Col1, Col2, etc. When I attempt to run a while loop on these nodes and check for null I still get a NullReferenceException. Can anyone suggest on how to handle this to avoid the exception?
int col = 1;
string colCount = col.ToString();
colCount = "Col" + colCount;
while (nodes[0][colCount].InnerText != null)
{
timeToFillValues.Add(double.Parse(nodes[0][colCount].InnerText));
col++;
colCount = "Col" + col.ToString();
}

Since you mentioned in comments the error happens when checking condition, there are only few cases where you should be getting an error:
if(nodes == null)
{
// was nodes not populated? Then populate it
}
if(nodes[0][colCount] == null)
{
// does element actually exist or is it null?
}
Check for these conditions before calling the while loop and you should find out wha tis causing the issue.

Related

Sonar issue Assignments should not be redundant (squid:S4165)

private void updateEmployee(String employeeCode, UpdateUserDto updateUserDto){
Employee emp = getEmpDetails(employeeCode);
emp = updateMobile&Email(emp, updateUserDto.getMobile(), updateUserDto.getMail());
// Remove this useless assignment; "emp" already holds the assigned value along all execution paths.
...
...
emp.setisActive(updateUserDto.getIsActive());
empRepo.save(emp);
}
private Employee updateMobile&Email(Employee emp, String mobile, String mail){
if(emp.getMobile() == null && (mobile != null || mobile.isBlank())){
emp.setMobile(mobile);
}
if(emp.getMail() == null && (getMail != null || getMail.isBlank())){
emp.setMail(mail);
}
return emp;
}
Due to connectivity complexity I made some functions. Above one is just for example, the code is bigger
Remove this useless assignment; "emp" already holds the assigned value along all execution paths.
At line 2 of updateEmployee()
Sonar issue details
Assignments should not be redundant (squid:S4165)
Noncompliant
a = b;
c = a;
b = c; // Noncompliant: c and b are already the same
Compilant
a = b;
c = a;
The emp parameter will be passed by reference into the updateMobile&Email method, meaning the line 2 assignment is unnecessary.
I suggest updating updateMobile&Email to have a void return type.

Deleting duplicate nodes from a sorted linked list

I'm trying to delete duplicate nodes from a sorted linked list. The code I used is -
Node* RemoveDuplicates(Node *head)
{
struct Node *ptr = head;
int var = ptr->data;
while(ptr != NULL)
{
var = ptr->data;
if(var == ptr->next->data)
{
ptr->next = ptr->next->next;
else
ptr = ptr->next;
}
return head;
}
Forget the free(ptr) statement, other than that I guess everything is fine but the above code is not working.
Is there any problem in the logic as I saw a similar code online but with one additional pointer?
Thanks in advance.
if(var == ptr->next->data)
should be
if (ptr->next != NULL && var == ptr->next->data)
No guarantees in your code that the next pointer is not null,

Why does Newtonsoft Replace function only replace the value if it is changed?

Take the following code:
JProperty toke = new JProperty("value", new JValue(50)); //toke.Value is 50
toke.Value.Replace(new JValue(20)); //toke.Value is 20
This works as expected. Now examine the following code:
JValue val0 = new JValue(50);
JProperty toke = new JProperty("value", val0); //toke.Value is 50
JValue val1 = new JValue(20);
toke.Value.Replace(val1); //toke.Value is 20
This also works as expected, but there is an important detail. val0 is no longer part of the toke's JSON tree, and val1 is part of the JSON tree; this means that val0 has no valid parent, while val1 does.
Now take this code.
JValue val0 = new JValue(50);
JProperty toke = new JProperty("value", val0); //toke.Value is 50
JValue val1 = new JValue(50);
toke.Value.Replace(val1); //toke.Value is 50
The behavior is different; val0 is still part of toke's JSON tree, and val1 is not. Now val0 has a valid parent, while val1 does not.
This is a critical distinction, and if you are using Newtonsoft JSON tree's to represent a structure, and storing JTokens as references into the tree, the way the references are structure can change based on the value being Replaced, which seems incorrect.
Is there any flaw with my reasoning? Or is behavior incorrect, as I believe it is?
I think you have a valid point: Replace should replace the token instance and set the parent properly even if the tokens have the same values.
This works as you would expect if the property value is a JObject and you replace it with an identical JObject:
JObject obj1 = JObject.Parse(#"{ ""foo"" : 1 }");
JProperty prop = new JProperty("bar", obj1);
JObject obj2 = JObject.Parse(#"{ ""foo"" : 1 }");
prop.Value.Replace(obj2);
Console.WriteLine("obj1 parent is " +
(ReferenceEquals(obj1.Parent, prop) ? "prop" : "not prop")); // "not prop"
Console.WriteLine("obj2 parent is " +
(ReferenceEquals(obj2.Parent, prop) ? "prop" : "not prop")); // "prop"
However, the code seems to have been deliberately written to work differently for JValues. In the source code we see that JToken.Replace() calls JContainer.ReplaceItem(), which in turn calls SetItem(). In the JProperty class, SetItem() is implemented like this:
internal override void SetItem(int index, JToken item)
{
if (index != 0)
{
throw new ArgumentOutOfRangeException();
}
if (IsTokenUnchanged(Value, item))
{
return;
}
if (Parent != null)
{
((JObject)Parent).InternalPropertyChanging(this);
}
base.SetItem(0, item);
if (Parent != null)
{
((JObject)Parent).InternalPropertyChanged(this);
}
}
You can see that it checks whether the value is "unchanged", and if so, it returns without doing anything. If we look at the implementation of IsTokenUnchanged() we see this:
internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
{
JValue v1 = currentValue as JValue;
if (v1 != null)
{
// null will get turned into a JValue of type null
if (v1.Type == JTokenType.Null && newValue == null)
{
return true;
}
return v1.Equals(newValue);
}
return false;
}
So, if the current token is a JValue, it checks whether it Equals the other token, otherwise the token is automatically considered to have changed. And Equals for a JValue is of course based on whether the underlying primitives themselves are equal.
I cannot speak to the reasoning behind this implementation decision, but it seems to be worth reporting an issue to the author. The "correct" fix, I think, would be to make SetItem use ReferenceEquals(Value, item) instead of IsTokenUnchanged(Value, item).

How to terminate a while loop when an Xpath query returns a null reference html agility pack

I'm trying to loop through every row of a variable length table on the a webpage (http://www.oddschecker.com/golf/the-masters/winner) and extract some data
The problem is I can't seem to catch the null reference and terminate the loop without it throwing an exception!
int i = 1;
bool test = string.IsNullOrEmpty(doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText);
while (test != true)
{
string name = doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
//extract data
i++;
}
try-catch statements don't catch it either:
bool test = false;
try
{
string golfersName = doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
}
catch
{
test = true;
}
while (test != true)
{
...
The code logic is a bit off. With the original code, if test evaluated true the loop will never terminates. It seems that you want to do checking in every loop iteration instead of only once at the beginning.
Anyway, there is a better way around. You can select all relevant nodes without specifying each <tr> indices, and use foreach to loop through the node set :
var nodes = doc.DocumentNode.SelectNodes("//*[#id='t1']/tr/td[3]/a[2]");
foreach(HtmlNode node in nodes)
{
string name = node.InnerText;
//extract data
}
or using for loop instead of foreach, if index of each node is necessary for the "extract data" process :
for(i=1; i<=nodes.Count; i++)
{
//array index starts from 0, unlike XPath element index
string name = nodes[i-1].InnerText;
//extract data
}
Side note : To query single element you can use SelectSingleNode("...") instead of SelectNodes("...")[0]. Both methods return null if no nodes match XPath criteria, so you can do checking against the original value returned instead of against InnerText property to avoid exception :
var node = doc.DocumentNode.SelectSingleNode("...");
if(node != null)
{
//do something
}

why doesn't it terminate?

var m_root : Node = root
private def insert(key: Int, value: Int): Node = {
if(m_root == null) {
m_root = Node(key, value, null, null)
}
var t : Node = m_root
var flag : Int = 1
while (t != null && flag == 1) {
if(key == t.key) {
t
}
else if(key < t.key) {
if(t.left == null) {
t.left = Node(key, value, null, null)
flag = 0
} else {
t = t.left
}
} else {
if(t.right == null) {
t.right = Node(key, value, null, null)
flag = 0
} else {
t = t.right
}
}
}
t
}
I wrote iterative version insert a node to binary search tree. I want to terminate when node is created, but it doesn't stop, because I think I didn't assign terminating condition. How to I edit my code to terminate when a node inserted in?
I'm not sure exactly what behaviour you want, but the cause is quite clear.
Your loop is a while condition, which will loop until t is null. So while t is non-null the loop will continue.
You only ever assign t to non-null values - in fact you're specifically checking for the null case and stopping it happening by creating a new node.
So either you need to reconsider your loop condition, or ensure t does in fact become null in some cases, depending on what your actual algorithm requirements are.
And since you're returning t at the bottom, I suggest the while condition is wrong; the only possible way this could terminate is if t is null at this point, so it would be pointless to return this anyway.
The first clause of your "if" statement in the loop
if(key == t.key) {
t
}
... does nothing if the comparison is true. It doesn't terminate the loop. The statement t is not synonymous with return t here. You can set flag = 0 at that point to terminate the loop.

Resources