crapolantern
crapolantern

Reputation: 81

c#: Dictionary TryGetValue creating instance instead of getting reference

I'm a total noob with c#, and cannot figure out why the same method works in different ways. I'm making a simple spreadsheet application, and am using a Dictionary of cells, where the key is a string name and the value is a Cell object:

public struct Cell
{
    private string Name { get; }
    public Object Content { get; set; }

    public Cell(string n, Object o)
    {
        Name = n;
        Content = o;
    }
}

Now, I'll need to be able to easily add/change the contents of the cell, so I've been doing this:

Dictionary<string, Cell> cells = new Dictionary<string, Cell>();

//  Assign new cell to 5.0 & print
cells.Add("a1", new Cell("a1", 5.0));
Console.WriteLine(cells["a1"].Content);     //  Writes 5

//  Assign cell to new content & print
cells.TryGetValue("a1", out Cell value);
value.Content = 10.0;
Console.WriteLine(cells["a1"].Content);     //  Writes 5
Console.ReadKey();

Of course, the dictionary creates the new cell just fine, but when I use TryGetValue, the new content for the cell doesn't make it to the actual object I'm trying to get. I was expecting the second print to be 10. In debug, it seems like it instantiates a new Cell instead of getting the reference of the cell at hand.

I've used a Dictionary before, and I've used TryGetValue to change properties of the existing object. So here's two questions: What am I doing wrong in this case, and what factors determine if the method returns a reference or not?

Upvotes: 2

Views: 3169

Answers (2)

NetMage
NetMage

Reputation: 26917

Cell is a struct. It is not recommended that you use a struct for objects that can be modified. I think you just found out why.

When TryGetValue returns the struct, it copies it into a value, which is a different struct than the one in the Dictionary.

Imagine if you replaced struct by int - another value type - would you expect assigning to the int from TryGetValue to change the Dictionary entry int?

If other constraints require you use a struct, you will need to update the cells Dictionary with the new struct, just as you would with any other value type:

Dictionary<string, Cell> cells = new Dictionary<string, Cell>();

//  Assign new cell to 5.0 & print
cells.Add("a1", new Cell("a1", 5.0));
Console.WriteLine(cells["a1"].Content);     //  Writes 5

//  Assign cell to new content & print
cells.TryGetValue("a1", out Cell value);
value.Content = 10.0;
cells["a1"] = value;  // update cells Dictionary
Console.WriteLine(cells["a1"].Content);     //  Writes 5
Console.ReadKey();

Upvotes: 3

Glitch
Glitch

Reputation: 142

You need to make your struct Cell into a class Cell.

That's because struct is a value type and it's content can't be changed by reference. If you want to go in detail, you can read about difference of value and reference types here.

Upvotes: 1

Related Questions