What could be null here? - c#

My app is crashing after I clear the Bing Map of its pushpins and then open a flyout. This is what I see in the debugger:
The textblock is definitely not null - it is defined declaratively in XAML.
The List of String (CurrentlyMappedPhotosets) is not null - as you can see, it contains a string / has a count of 1.
The code just before what's seen on the scream shot is:
int count = App.CurrentlyMappedPhotosets.Count;
What could be null here?
Just before this happens, I call ClearMap:
private void ClearMap()
{
var mapLayerChildren = from c in DataLayer.Children select c;
var kinderGarten = mapLayerChildren.ToArray();
for (int i = 0; i < kinderGarten.Count(); i++)
{
if (kinderGarten[i] is Pushpin)
{
DataLayer.Children.Remove(kinderGarten[i]);
}
}
CloseInfobox();
App.CurrentlyMappedPhotosets.Clear();
if (null != App.photosetLocationCollection)
{
App.photosetLocationCollection.Clear();
}
appbarbtnClearMap.IsEnabled = false;
UpdateGUI(false);
}
...which calls UpdateGUI():
private void UpdateGUI(bool resizeMap)
{
appbarbtnRenamePhotoset.IsEnabled = App.CurrentlyMappedPhotosets.Count > 0;
if (resizeMap)
{
ResizeMap();
}
}

Have you looked if the value present in the collection is not null?
Any non primitive type class is by default null if not constructed with a value.
So you can have as many null values of the type you are trying to have.
I suggest that you do a test by changing the line to:
textblock0.Text = App.CurrentlyMappedPhotosets[0].HasValue ? App.CurrentlyMappedPhotosets[0].Value : "";

Related

Getter and Setter c#

I have multiple objects(nodes) and each node has a getter and setter for a list named Calea which contains other nodes, also each node has neighbours and they are also nodes . The problem is that list is stacking up and I can't figure out why , it's like a static variable and also I am not using that getter and setter anywhere else.
Here is my code :
private int cost = 10000;
private LinkedList<GraphNode<string>> calea=new LinkedList<GraphNode<string>>() ;
public int Cost
{
get
{
return cost;
}
set
{
cost = value;
}
}
public LinkedList<GraphNode<string>> Calea
{
get
{
if (calea == null) return new LinkedList<GraphNode<string>>();
return calea;
}
set
{
calea = value;
}
}
Code above shows the method for Cost and Calea , Cost works fine but Calea is stacking up.The code below is a sample of code of how I am setting the value Calea for each node:
if (curr.Neighbors.ElementAt(i).Cost > curr.Costs.ElementAt(i) + curr.Cost)
{
curr.Neighbors.ElementAt(i).Cost = curr.Costs.ElementAt(i) + curr.Cost;
curr.Neighbors.ElementAt(i).Calea = curr.Calea;
curr.Neighbors.ElementAt(i).Calea.AddLast((GraphNode<string>)curr.Neighbors.ElementAt(i));
index = i;
}
++i;
The sample code where I change the current node below:
pathNodesToVisit.Remove(curr);
if (pathNodesToVisit.Count == 0) break;
if (curr.Neighbors.Count > index)
{
for (int j = 0; j < pathNodesToVisit.Count; j++)
{
if (pathNodesToVisit.ElementAt(j).Value == curr.Neighbors.ElementAt(index).Value)
{
indexx = j;
//MessageBox.Show(pathNodesToVisit.ElementAt(j).Value);
}
}
curr = pathNodesToVisit.ElementAt(indexx);
}
else
{
curr = pathNodesToVisit.ElementAt(0);
}
A few words : pathNodesToVisit are all the nods which I want to visit(Dijkstra algorithm) , in the code above I remove the curr node from the list and the new curr node is a node which had the Costs and Calea changed.
I have no idea what you mean by "stacking up," but:
public LinkedList<GraphNode<string>> Calea
{
get
{
if (calea == null) return new LinkedList<GraphNode<string>>();
return calea;
}
... creates a new list every time the property is read, not just the first time. calea will always be null with this approach.
Try
get
{
if (null == calea)
calea = new LinkedList<GraphNode<string>>();
return calea;
}
Update
The line
curr.Neighbors.ElementAt(i).Calea = curr.Calea;
Does not make a copy of the list. It copies a reference to the list. Any changes made to any node's calea afterward will affect every node, not just the one you're after.
Try
curr.Neighbors.ElementAt(i).Calea = new LinkedList<GraphNode<string>>(curr.Calea);
Though, you should make sure .Neighbors actually has an element i before doing this, among other things.
Note: In the case of an uninitialized node, this will actually create two lists - once when Calea is read (LH of the expression, which calls your .get), and another on the right.
There are many ways to copy a collection. I suggest googling c# deep copy LinkedList<T>.

Unable to cast from string to generic list in C#

I have written a code to store uploaded image names into the session list.
A user can upload only 4 images, so there will be max 4 image names in a session.
A user can upload 1, 2, 3 or 4 images based on requirement. If a user selects only 2 images, the session will have only 2, so the rest 2 will throw index out of bound exception!
to handle such situation i have written following code.
string image1 = "";
string image2 = "";
string image3 = "";
string image4 = "";
var imageSessList = (List<string>)Session["Images"];
if (imageSessList != null)
{
for (int i = 0; i < imageSessList.Count; i++)
{
if (imageSessList[i] != null && i == 0)
{
image1 = imageSessList[i];
}
if (imageSessList[i] != null && i == 1)
{
image2 = imageSessList[i];
}
if (imageSessList[i] != null && i == 2)
{
image3 = imageSessList[i];
}
if (imageSessList[i] != null && i == 3)
{
image4 = imageSessList[i];
}
}
}
But now it's showing following error: "Unable to cast object of type 'System.String' to type 'System.Collections.Generic.List"
How can I resolve it, or is there any way to complete this functionality.
The problem is that Session["Images"] doesn't contain a list but a string. You have to correct this on the setting side.
A general solution to prevent such errors is by wrapping the session state into a class, and using the typed properties from that class for getting and setting:
public static class SessionState
{
public List<string> Images
{
get
{
return HttpContext.Current.Session["Images"] as List<string>;
}
set
{
HttpContext.Current.Session["Images"] = value;
}
}
}
Now you can just get and set SessionState.Images.
From previously mentioned comments:
#StephanBauer i have written following lines in foreach: lstImageNames.Add(destFileName); context.Session["Images"] = lstImageNames; – ace 22 mins ago
If context.Session["Images"] = lstImageNames; is done in foreach loop, then you are overwriting the value in the session each time.
One more thing i wanted to point out is, string can not only be null but empty too. So, you may want to change your null checks as (just a suggestion):
if (!string.IsNulOrEmpty(imageSessList[i])l && i == 0)

Data Binding DataGridView to ComboBox Throwing Null Value Exception

I am trying to to bind data from DataGridView in two ComboBoxes. In ComboBox one is cbosearchby and other cbosearchvalue. cbosearchby is working perfectly but when select searchvalue error being thrown. Please help me to sort out it.
Error is :
Value cannot be null.Parameter name: value
Here is my code:
private void cboSearchBy_SelectedIndexChanged(object sender, EventArgs e)
{
cboSearchValue.Items.Clear();
cboSearchValue.Text = "";
if (cboSearchBy.SelectedIndex != -1)
{
var source = new AutoCompleteStringCollection();
string[] sValues = new string[0];
foreach (DataGridViewRow dr in dataGridView1.Rows)
{
if (!cboSearchValue.Items.Contains(dr.Cells[cboSearchBy.SelectedItem.ToString()].Value))
{
cboSearchValue.Items.Add(dr.Cells[cboSearchBy.SelectedItem.ToString()].Value);
Array.Resize(ref sValues, sValues.Length + 1);
sValues[sValues.Length - 1] = Convert.ToString(dr.Cells[cboSearchBy.SelectedItem.ToString()].Value);
}
}
source.AddRange(sValues);
cboSearchValue.AutoCompleteCustomSource = source;
}
}
If the value you're passing to Contains() is null, then it'll throw an exception.
Here's what's going on internally when you call the Contains() method:
public bool Contains(object value)
{
return IndexOf(value) != -1;
}
public int IndexOf(object value)
{
if (value == null)
throw new ArgumentNullException("value");
return InnerList.IndexOf(value);
}
To fix this, you need to check for null separately:
var searchValue = dr.Cells[cboSearchBy.SelectedItem.ToString()].Value;
if (searchValue != null && !cboSearchValue.Items.Contains(searchValue))
{
...
...
The problem here could be with this statement :
cboSearchValue.Items.Clear();
This is called immediately at the entry point of your functions and this will erase all items from your drop-down. And further in your code, you are using Contains() on that same drop-down. Since the drop-down will already be empty, you wont be able to use Contains(), suffice to say that you will receive an exception there. You might want to remove that statement from there.
I dont know what exactly your logic here is, but you can try according to the above mentioned thing.
Hope this helps.

does passing a collection to a function means the function can change the collection's elements?

I actually know the answer to the question (I think) but I don't know the reason...
So, I know that if I have a class like the following:
class Man
{
public string Name;
public int Height;
public Man() { }
public Man(string i_name, int i_height)
{
Name = i_name;
Height = i_height;
}
}
And I have the following Program class (with main function):
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Man g = new Man("greg", 175);
//assigning null to g inside the function.
p.ChangeMan(g);
Console.WriteLine(g == null? "the function changed g out side the function" : "the function did not change g out side the function");
//the output of course is that the function did not change g outside the function.
//now I am creating a list of Man and adding 5 Man instances to it.
List<Man> manList = new List<Man>();
for (int i = 0; i < 5; i++)
{
manList.Add(new Man("Gadi" + i.ToString(), 10 * i));
}
//assigning null to the list insdie the function
p.ChangeList(manList);
Console.WriteLine(manList == null ? "the function changed the list out side the function" : "the function did not change the list out side the function");
//the output of cousre again is the function did not change the list out side the function
//now comes the part I dont understand...
p.ChangeManInAList(manList);
Console.WriteLine("list count = " + manList.Count());
//count is now 6.
Console.WriteLine(manList[0] == null ? "the function changed the element out side the function" : "the function did not change the element out side the function");
//the out again - the function did not change...
}
public void ChangeMan(Man g)
{
g = null;
}
public void ChangeManInAList(IList<Man> gadiList)
{
Man g = gadiList.First<Man>();
g = null;
Console.WriteLine(g == null? "g is null" : "g is not null");
gadiList.Add(new Man("a new gadi", 200));
Console.WriteLine("list count = " + gadiList.Count());
}
public void ChangeList(List<Man> list)
{
list = null;
}
}
I am assigning null to the first element of the list + adding one Man to the list. I expected that if I can add to the list, I can also change the elements, but I saw different...
I was able to add a Man to the list but could not assign null to one of the elements, how come? I know the list is passed by value so I can not change the list itself (like assigning null to it), but I can add to it? and can not assign null to the elements? are they being passed by val as well?
will be happy for some good and clear explanation :)
Here is your point of confusion:
Man g = gadiList.First<Man>();
g = null;
What you are essentially doing is getting a Man out of the list and assigning it to the local variable g.
Then, you assign a different value to the variable g.
At no point here did you change the value of any member of the list, you simply changed the value which the variable g refers to.
Let's try to compare it to this example:
int a = 5;
int b = a;
b = 3;
//you wouldn't expect `a` to be 3 now, would you?
In order to change the value of the list item, you would need to explicitly set the list index to a different value:
Man g = gadiList.First<Man>();
gadiList[gadiList.IndexOf(g)] = null;
//or specifically in this case:
gadiList[0] = null;
When you get element from list you get new reference to list item.
So as a result you get two references: one (private reference in list object), your reference.
When you set your reference to null it do not affect reference in list object. You reference became null, but private list reference remains the same.

Using database query results instead of displaying in datagrid

I am using C# to create a Silverlight 4 application.
I am trying to do the following:
MapNode endNode = null;
if (keyword != null && keyword != "")
{
EntityQuery<NodeIDProj> res = CampusQueries.getNodeIDByNameQuery(keyword);
var queryres = CampusQueries.Load<NodeIDProj>(res, (items) =>
{
foreach (var item in items.Entities)
{
MapNode n = mapHelp.getNodeByID(item.NodeID);
if (n != null)
{
endNode = n;
TrackAnimation();
}
}
}, true);
}
However, after this point, my variable endNode is still null. TrackAnimation() works as though endNode has a valid value, but outside of the Load statement, endNode is back to null.
I know that I am lacking in understanding of how this works, and I would really appreciate an help given.
What I am trying to do, is query my database and I want to use those results in other methods rather than displaying them in a datagrid.
I want endNode to have value which I can use in other methods.
Please help me to figure out a way to do this, thank you!
EDIT:
Thank you, SLaks
Can I do something like:
MapNode endNode = null;
if (keyword != null && keyword != "")
{
EntityQuery<NodeIDProj> res = CampusQueries.getNodeIDByNameQuery(keyword);
var queryres = CampusQueries.Load<NodeIDProj>(res, (items) =>
{
foreach (var item in items.Entities)
{
MapNode n = mapHelp.getNodeByID(item.NodeID);
if (n != null)
{
endNode = n;
TrackAnimation();
}
}
}, true);
}
queryres.Completed += new EventHandler(queryres_Completed);
void queryres_Completed(object sender, EventArgs e)
{
//stuff
}
If so, how can I get access to the endNode variable, as it is declared within another method?
Your Load method is probably asynchronous, meaning that the callback happens some time after the rest of your code runs.
You can only use the result after you actually receive it.

Categories