Проблема - что, если я делаю:
ListaDeListas = {{"1","2","3"},{"4","5","6"},{"7","8","9"}...}
List<string> Lista = new List<string>();
Lista = ListaDeListas[0];
До сих пор все добро, тогда Вы, когда вслед за:
Lista.Add("1");
Lista.Add("2");
Lista.Add("3");
Здесь я подтверждаю значение ListaDeListas
и Вы даете мне:
ListaDeListas = {{"1","2","3","1","2","3"},{"4","5","6"},{"7","8","9"}...}
Я понимаю, что в этом кодексе значение ListaDeListas
Вы были бы должны пребывать неизменными, но, может быть, есть что-то, что теряло бы меня, или какое-то понятие, которое Вы считали бы ошибочным.
Почему происходит это?
Ошибка в asignaciГіn переменных
BГЎsicamente не ошибка. Чтобы мочь подтверждать это, нужно понимать две концепции фиксируй: Типа ссылки и Типа стоимости .
Типа ссылки:
Способствует тому, чтобы каждый раз, когда мы использовали переменную, прошла ссылка.
Например:
using System;
class A
{
public int b = 9;
}
class Program
{
static void Main()
{
A a = new A();
Console.Write(a.b);
A c = a;
c.b = 10;
Console.Write(a.b);
}
}
ВїPor quГ© дал как оказанный 10?
Это ему должно porquГ© его estГЎ перемещая ссылку первоначального объекта a
на c
. Но это возможное porquГ© идентификатор A
- класс (классы в C# - тип ссылки ).
Давайте Анализировать cГіdigo по частям:
1. Уедь:
A a = new A();
cГіdigo наверху того, что он делает, состоит в том, чтобы создавать объект и ему распределяется она direcciГіn основание объекта в указатель implГ - я упоминаю a
. По умолчанию, признак b
tendrГЎ хранившаяся стоимость 9.
2. Уедь:
Console.Write(a.b);
A c = a;
печатает на экране контент признака b
(один 9
) и ademГЎs этого, перемещают в указатель c
ее его direcciГіn памяти, которая считала бы сохраняемым указатель a
. Тогда, поскольку ты можешь видеть, у указателя c
есть первоначальная ссылка объекта, на который указывал указатель a
.
3. Уедь: Такой
c.b = 10;
Console.Write(a.b);
Как указатель implГ - упомянул c
у него есть тот же контент a
, я могу изменять признак первоначального объекта и из-за этой razГіn, печатает один 10, porquГ© указатели a
и b
, они указывают на тот же объект.
Типов стоимости:
Способствует тому, чтобы каждый раз, когда мы использовали переменную, прошла копия данных.
Например:
using System;
struct A
{
public int b;
public A(int b)
{
this.b = b;
}
}
class Program
{
static void Main()
{
A a = new A(9);
A c = a;
c.b = 10;
Console.Write(a.b);
}
}
ВїPor quГ© дал как оказанный 9?
Это проистекает porquГ© estГЎ перемещая копию информации. Но это возможное porquГ© идентификатор A
- структура (struct
в C# - тип стоимости ).
Давайте Анализировать cГіdigo по частям:
1. Уедь:
A a = new A(9);
cГіdigo наверху способствует тому, чтобы указатель a
сослался на объект (где он envГ - в информацию в первого parГЎmetro строителя).
2. Уедь:
A c = a;
Это часть mГЎs важная, благодаря тому, что, не он estarГ - в перемещая ссылку первоначального объекта (в которое я указал на a
), а mГЎs добро, estarГ - в создавая новый объект, он это означает, что указатель c
tendrГЎ сохраняемый одна direcciГіn основание нового объекта (это не объект, который указывает на a
). Тогда после новый объект был создан раньше, составитель берется за то, чтобы перемещать контент (признаки) первоначального объекта в новый объект (в который он указывает на c
).
Для того, чтобы он остался mГЎs ясно, этот cГіdigo:
A c = a;
эквивалентный в:
A c = new A(0);
c.b = a.b;
Во втором cГіdigo отражается mГЎs, функционирование:
создает новый объект.
перемещают его копию данных, что tenГ - в предыдущий объект, в новый объект.
С этой explicaciГіn, podrГ-хозяева отвечать rГЎpidamente твое сомнение и тревогу.
В примере, который ты показал, estГЎs создавая список объектов, только, что каждый объект serГЎ типа List<string>
(поэтому razГіn, ему говорится список списков, а именно, в списке, tendrГЎs несколько списков).
Тогда, как List - класс, serГЎ Тип ссылки .
cГіdigo, который ты показал:
Lista = ListaDeListas[0];
В действительности, что estГЎs происходя ahГ, - это та direcciГіn основание первого элемента, у которого был список объектов.
Каждое изменение, которое ты делаешь с указателем implГ, - упомянул Lista
, он окажется отраженным в ListaDeListas[0]
. Но ты darГ© пример mГЎs ясный для того, чтобы ты это понял лучше.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<string> list1 = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();
List<List<string>> lists = new List<List<string>>();
lists.Add(list1);
lists.Add(list2);
lists[0].Add("1");
lists[0].Add("2");
lists[0].Add("3");
lists[1].Add("4");
lists[1].Add("5");
lists[1].Add("6");
list3 = lists[0];
list3.Add("1");
list3.Add("2");
list3.Add("3");
foreach(string l in list3)
Console.Write(l + "\n");
Console.ReadLine();
}
}
Это дает как результат:
1
2
3
1
2
3
ВїPor quГ© дал этот результат?
, Чтобы знать porquГ©, explicarГ© шаг за шагом, cГіdigo наверху.
1. Уедь:
List<string> list1 = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();
BГЎsicamente aquГ,, - где создает 3 список объектов типа string
.
2. Уедь:
List<List<string>> lists = new List<List<string>>();
lists.Add(list1);
lists.Add(list2);
создает список объектов типа List<string>
и despuГ©s, aГ±ade два объекта типа List<string>
.
3. Уедь:
lists[0].Add("1");
lists[0].Add("2");
lists[0].Add("3");
lists[1].Add("4");
lists[1].Add("5");
lists[1].Add("6");
В этом cГіdigo уходит aГ±adiendo объекты типа string
в два ты заносишь в список (list1
и list2
), что estГ©n хранение в списке типа List<string>
.
До того, как Гєltima объясняет, уезжает cГіdigo, чтобы отвечать на твое сомнение, ты dibujГ© форма как podrГ, - когда это, отраженное в памяти быть:
B1:
|0x0F| -> B2: |0x0F|0x04|0x05|
|0xFF| -> B3: |0xFF|0x08|0x09|
Блок 1 (B1
) - список списков и каждый элемент tendrГЎ она direcciГіn основание списка объекта типа string
.
Блок 2 (B2
) - список типа string
и каждый элемент tendrГЎ она direcciГіn основание объекта типа string
.
Блок 3 (B3
) - список типа string
и каждый элемент tendrГЎ она direcciГіn основание объекта типа string
.
3. Уедь:
list3 = lists[0];
В нашем mapita памяти, мы знаем, что lists[0]
darГ - в как оказанный она direcciГіn 0x0F
, bГЎsicamente эта та direcciГіn, что tendrГЎ сохраняемая указатель list3
.
3 Уезжает:
list3.Add("1");
list3.Add("2");
list3.Add("3");
AquГ - aГ±adimos 3 объекта типа string
в list3
. Но если мы уходим в наш mapita памяти, estarГ-хозяев добавляя 3 адреса основания этих объектов в блоке 2.
Тогда, наш mapita становится отвечающим современным требованиям: Такие
B1:
|0x0F| -> B2: |0x0F|0x04|0x05|0x20|0x21|0x22|
|0xFF| -> B3: |0xFF|0x08|0x09|
Как блок 2 представляет список объектов, который манипулирует list3
, estarГ-хозяина aГ±adiendo 3 базовыми адресами этих объектов в B2.
Сейчас, если мы печатаем контент блока 2 (который bГЎsicamente является блоком, который манипулирует указателями list3
и lists[0]
), мы darГ - в как результат 123123
.
Поэтому razГіn, печатает нам этот результат, как lists[0]
считает сохраняемой ее direcciГіn 0x0F
и list3
tambiГ©n считает хранившейся саму direcciГіn, тогда любое изменение verГЎ отраженный в B2
(в блоке 2 из нашего mapita памяти, которая bГЎsicamente как будто это был первый список объектов типа string
).