1

If I put an object in the dictionary, whether it becomes a pointer?

I have the following dictionary:

public Dictionary<string, Class1> Dic{ get; set; }

In the following function I update / add to the dictionary

    private void Update(string Name)
    {
        if (Name== null || Name=="")
            return;
        if (Dic.ContainsKey(Name))
        {
            Dic[Name] = MyClass;
        }
        else
        {
            Dic.Add(Name, MyClass);
        }
    }

MyClass is a variable that sitting in the same class with the dictionary

public Class1 MyClass { get; set; }

When i changed the class i call to update function, i see that all the dictionary contaion the same value: current MyClass , why?

How can I prevent this?

Hodaya Shalom
  • 4,327
  • 12
  • 57
  • 111
  • I've up voted this question as I think its covers an important lesson in Reference and Value Types. – Derek Mar 07 '13 at 10:32
  • Unless you show some code that shows how/where you are adding multiple values into the dictionary, we can't really comment on how they "contaion the same value: current MyClass". The most obvious answer would be: because you told it to, by adding the same object against every key. – Marc Gravell Mar 07 '13 at 10:32

5 Answers5

2

You are adding the same class object against multiple keys in your dictionary, but all of them are pointing to the same object that is why when you change one object, you see the changes across the dictionary. You need to make copy of your class object and then add it to the dictionary.

You may see this discussion: How do you do a deep copy an object in .Net (C# specifically)? on Stackoverflow.

Other than that, you can get rid of your check against keys, since you are checking if the key doesn't exist add, otherwise update. you can simply do:

private void Update(string Name)
    {
        if (Name== null || Name=="")
            return;
        Dic[Name] = MyClass;
    }

Which would do the same (add if doesn't exist and update if exist)

Community
  • 1
  • 1
Habib
  • 219,104
  • 29
  • 407
  • 436
1

Because the class you put in is by reference, so when you change it someplace, it 'changes' there, too (it doesn't really change there, it only changes in one place, but we're all looking at the same thing, so to speak). So, it's nothing really to do with the dictionary, but the mechanics of .NET.

You wouldn't see such changes reflected if you put a value type in, say an integer, then changed the variable value. You could define structures, if appropriate for your situation, which are value types, and you could 'reuse' the type without 'cascading changes'.

Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
1

No. And sort-of-yes. You never "put and object in the dictionary" - you actually put a reference to an object into the dictionary. The reference points to the original object : the object is not cloned.

If Class1 was a struct, then it would indeed be copied whenever you access it or insert it.

In human terms: a reference is the written address to a house, say. Lots of people can have a copy of that address. If somebody goes to the house and paints the door red, then that is seen by everyone who looks at that address.

(I think I stole this analogy from Jon; sorry Jon)

It sounds like you are doing something like:

MyClass obj = new MyClass();
foreach(var name in names) {
    obj.Update(name);
}

when you should be doing:

foreach(var name in names) {
    MyClass obj = new MyClass();
    obj.Update(name);
}

The distinction here is how many objects we have.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • @Derek I've asked the OP to clarify that very thing, but yes it sounds like they are adding the same object reference against multiple keys – Marc Gravell Mar 07 '13 at 10:35
  • I think your right, it looks as though the same object is being used on each update rather than a new one Initialised, great analogy, even if it is stolen lol. – Derek Mar 07 '13 at 10:43
0

Because class is a reference type. That means every variable of that type is a pointer to that type.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • "a *reference* to that object" would be better phrasing; "pointer" has a different usage, and it isn't referring to a "type" – Marc Gravell Mar 07 '13 at 10:30
0

Your class is a reference type, so Dictionary contains it's memory link. Actually you can check more at reference types and value types

Sergio
  • 6,900
  • 5
  • 31
  • 55