开发者

Pointer to a dictionary<> in c#

开发者 https://www.devze.com 2023-02-19 16:11 出处:网络
I have a class, which its constructor is below public GroupsForm(ref Dictionary<string, List<string>> groupsList)

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:

Pointer to a dictionary<> in c#


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#.

0

精彩评论

暂无评论...
验证码 换一张
取 消