I have a class, which its constructor is below
public GroupsForm(ref Dictionary<string, List<string>> groupsList)
I want to use the groupsList in other functions as well so I declared a private member in the class:
private Dictionary<string, List<string>> _groupsList;
But the problem开发者_C百科 is when I do _groupsList = groupsList;
it makes a copy of the groupsList
and changes made to _groupsList
doesn't change groupsList
, as I think it makes a deep copy by default. What I want is that it should point to that list.
In C++, this can easily be done via pointers, but can anyone tell me how can I do this in C#?
Ahmed has posted this image:
There are value types and reference types in C#. A dictionary is a reference type so whenever assigning a variable that holds a reference type to another, the reference is copied, which means that both variables will be holding the same data. So, if you change the data, you should expect it to change on both variables:
List<int> list1 = new List<int>() { 1, 2, 3 };
List<int> list2 = list1;
list2.Add(10);
list1.ForEach(x => Console.WriteLine(x)); // should print 1, 2, 3 and 10.
However, if you reassign the variable, then you are not changing the data:
List<int> list1 = new List<int>() { 1, 2, 3 };
List<int> list2 = list1;
list2 = new List<int>() { 10, 11, 12 };
list1.ForEach(x => Console.WriteLine(x)); // should print 1, 2, 3 only
One thing that caught my attention in your code though was that the constructor is expecting a ref
. This means that you are passing the reference itself by reference, which in C++ would be something like a double pointer (type**
). You'd do this if, in the snippet above, you want to have this effect:
void MethodA(ref List<int> list)
{
list = new List<int>() { 10, 11, 12 };
}
// ...
List<int> list1 = new List<int>() { 1, 2, 3 };
MethodA(ref list1);
list1.ForEach(x => Console.WriteLine(x)); // should print 10, 11, 12
One more thing -- AFAIK C# doesn't implement deep copies in any of it classes. You have to do it yourself.
In your InitGroups method, you've got an assignment statement to _groupsList - it's this new list that contains 3 items. You could change InitGroups to do something like:
var newGroups = (Dictionary<string, List<string>>)ser.ReadObject(reader,true);
foreach(var kvp in newGroups)
{
_groupsList.Add(kvp.Key,kvp.Value);
}
And then you'll still be working with the same Dictionary object.
You don't need the ref
in your method signature. Objects are passed by reference anyway.
And no, there is no copying going on.
But the problem is when I do _groupsList = groupsList; it makes a copy of the groupsList
No, it does not. It copies a pointer. List is a reference type.
as I think it makes a deep copy by default
Think again. Your conclusion is wrong.
List<T>
is a reference type, so all variables are pointers. Beginner C#, first week, first day, first hour. Go back and read the introduction then look for the error in the rest of your code you do not show us.
You are wrong on several points.
C# references are totally different from C++.
In short, you should not use ref
here because it's for propagating assignments made to parameter to the calling code which is not what you mean.
You are wrong assuming there's any kind of copying involved here.
groupsList
and _groups ist
are two references pointing to the same object in memory.
You'll need to read more about reference and value types in C#.
精彩评论