Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18

Как сделать так, чтобы по ссылке класса А оказался класс Б

14.02.2014, 15:17. Показов 1878. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Есть Dictionary, содержащий экземпляры класса "Книга". Есть другие классы, ссылающиеся на эти экземпляры, допустим на А. Допустим, я делаю А = Б. Б - тоже экземпляр класса "Книга", просто содержащиеся в нем данные другие. Грубо говоря, я делаю "Книга недописанная" = "Книга дописанная".

Насколько я понимаю, те классы, которые ссылаются на экземпляр класса, содержащего "Недописанная книга" не увидят новые данные из экземпляра с "Написанная книга". То есть, если сделать А = Б, то это не заменяет А на Б. "А" остается самостоятельно, а "Б" - самостоятельно.

Вопрос: как сделать так, чтобы по ссылке класса А оказался класс Б?
Подвопрос: Класс А, в этом случае куда девается?

Что хочется:
1. Внешний код имеет ссылки только на А.
2. Б формируется непрерывно. Обновлять ссылки внешнего кода не хочется.
3. Желательно, чтобы внешний код, обращаясь к экземпляру А видел экземпляр Б.

Заранее спасибо!

Добавлено через 8 минут
Можно, конечно, скопировать содержимое Б в А, но структура класса может измениться, а метод копирования желательно не трогать.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.02.2014, 15:17
Ответы с готовыми решениями:

Как сделать так, чтобы был доступ к методу вложенного класса, если объявлен только внешний класс
То есть если в классе Class есть вложенный класс innerClass с методом method() была возможна такая вещь: Class class = new Class(); ...

как сделать так, чтобы скрипт постоянно переходил по ссылке
Подскажите, как сделать чтобы скрипт постоянно переходил по ссылке(после перехода он вернется на ту же страницу), но при появлении на...

Как сделать так, чтобы значения экземпляров класса не повторялись
Я пытаюсь написать игру 2048. Коротко об игре, для тех кто не знает: Есть поле 4х4 в нем появляются на случайной позиции квадратики с...

12
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
14.02.2014, 15:40
Что-то плохо понятно, при чём тут Dictionary.
Цитата Сообщение от Rammal Посмотреть сообщение
То есть, если сделать А = Б, то это не заменяет А на Б.
Заменяет.
Цитата Сообщение от Rammal Посмотреть сообщение
Класс А, в этом случае куда девается?
Если на него больше нет ссылок, то будет собран сборщиком мусора (garbage collector).
0
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18
14.02.2014, 15:51  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
Заменяет.
Да, опыта мне не хватает грамотно объяснить. Попробую изложить на примере псевдокода.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Page
{
     public string textPage;
     public Page(string newText)
     {
            textpage = newText;
     }
}
 
class Book
{
     public Dictionary<string, Page> pages
}
 
class WorkCod
{
     Page firstPage = new Page("12345");
     Book book = new Book();
     book.pages.add("page1", firstPage)
     
     myPage = book.pages["page1"];
 
     Page secondPage = new Page("67890");
     book.pages["page1"] = secondPage; // затык вот тут. надо как-то заменить (можно, скопировать, но как? класс Page может меняться)
 
     Console.WriteLine(myPage.textPage)
}
Вот хотелось бы, чтобы в самом конце на консоли было 67890, а не 12345.


Цитата Сообщение от dondublon Посмотреть сообщение
Если на него больше нет ссылок, то будет собран сборщиком мусора (garbage collector).
Спасибо за ответ.
0
484 / 439 / 123
Регистрация: 05.01.2010
Сообщений: 1,848
14.02.2014, 16:00
C#
1
myPage = book.pages["page1"];
поставьте после
C#
1
book.pages["page1"] = secondPage;
0
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18
14.02.2014, 16:08  [ТС]
Цитата Сообщение от valera_21 Посмотреть сообщение
[CSHARP]
поставьте после
Валера, спасибо конечно.
Но это, как я писал выше, псевдокод. Последовательность имеет важное значение. Я лишь примерно показал алгоритм. То есть если бы задача стояла именно по этому коду - я бы так и сделал.

Но вопрос в другом: как, имея именно такую последовательность, так присвоить, чтобы заменить. По ссылке? Гуглю вот...
0
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
14.02.2014, 16:12
никак. меняйте алгоритм
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
14.02.2014, 16:13
Ну, в общем, резонное поведение.
Вы присвоили myPage ссылку первую страницу, и так оно и остаётся до конца.
Как вариант - хранить не ссылку на класс, а ключ - "page1", поскольку такова ваша логика.
0
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18
14.02.2014, 16:21  [ТС]
Цитата Сообщение от da1z Посмотреть сообщение
никак. меняйте алгоритм
Погодите-погодите... Как это "никак"? Как минимум один способ я знаю. Даже два способа.

Первый это

C#
1
2
3
4
5
void Copy(Page oldPage, Page newPage)
{
    oldPage.textPage = newPage.textPage;
    // и так остальные поля
}
Первый должен работать однозначно.

Второй способ вроде как описан у Троелсена как "передача ссылочных типов по ссылке". Что-то вроде:
C#
1
2
3
4
public static void SendByReference<T>(T newObject, ref T oldObject)
        {
            oldObject = newObject;
        }
Второй не пробовал, да он вроде как и не подойдет. У меня dictionary, а свойство, индексатор или динамический член не может передаваться как параметр с ключевым словом out или ref.

Цитата Сообщение от dondublon Посмотреть сообщение
Как вариант - хранить не ссылку на класс, а ключ - "page1", поскольку такова ваша логика.
Согласен, тоже вариант рассматривался. Но в Dictionary может быть несколько тысяч элементов, обращаться к нему будут очень и очень часто. И вот тут уже другой вопрос: обращение по ключу будет с такой же скоростью, с какой рабочий код будет обращаться к экземпляру класса по ссылке?
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
14.02.2014, 16:27
Rammal, что-то вы мудрите.
Переприсвойте myPage и дело с концом.
Если для вас сложно отследить момент замены значения в словаре по ключу "page1" - то тут уже сложнее, надо использовать события. А классы друг в друга копировать - буэээээ.... Занятие долгое, бессмысленное и неблагодарное.

Добавлено через 54 секунды
Цитата Сообщение от Rammal Посмотреть сообщение
Согласен, тоже вариант рассматривался. Но в Dictionary может быть несколько тысяч элементов, обращаться к нему будут очень и очень часто. И вот тут уже другой вопрос: обращение по ключу будет с такой же скоростью, с какой рабочий код будет обращаться к экземпляру класса по ссылке?
Нет, обращение по ключу будет медленнее. Но куда быстрее, чем то, что вы затеяли (копирование классов).

Добавлено через 2 минуты
Цитата Сообщение от Rammal Посмотреть сообщение
Но в Dictionary может быть несколько тысяч элементов,
Я, конечно, не знаю вашей задачи и требований к быстродействию, но это не так уж много. И всё-таки подумайте над вашей логикой, для начала. Может, сначала переприсваивать ссылку на класс, а потом в словарь. Можно, сам класс должен будет содержать ссылку на данные. Думайте, короче.
1
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18
14.02.2014, 16:29  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
Переприсвойте myPage и дело с концом.
Увы, тоже не вариант. Экземпляров Book тоже очень много.

Цитата Сообщение от dondublon Посмотреть сообщение
Если для вас сложно отследить момент замены значения в словаре по ключу "page1" - то тут уже сложнее, надо использовать события. А классы друг в друга копировать - буэээээ.... Занятие долгое, бессмысленное и неблагодарное.
Спасибо, скорее всего буду использовать события, замерять скорость, сравнивать с другими вариантами решения.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.02.2014, 00:22
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication123
{
    class Page
    {
        public string textPage;
        public Page(string newText)
        {
            textPage = newText;
        }
    }
 
    class Book
    {
        public Dictionary<string, Page> pages = new Dictionary<string, Page>();
    }
 
 
    class Program
    {
        private static void Main(string[] args)
        {
            Page firstPage = new Page("12345");
            Book book = new Book();
            book.pages.Add("page1", firstPage);
 
            Func<Page> myPage = () => book.pages["page1"];
 
            Page secondPage = new Page("67890");
            book.pages["page1"] = secondPage;
            // затык вот тут. надо как-то заменить (можно, скопировать, но как? класс Page может меняться)
 
            Console.WriteLine(myPage().textPage);
        }
    }
}
0
0 / 0 / 1
Регистрация: 10.01.2014
Сообщений: 18
15.02.2014, 14:09  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
C#
1
            Func<Page> myPage = () => book.pages["page1"];
Если не сложно, поясните как это решает проблему?
Дело в том, и как уже говорилось, я представил лишь псевдокод.

Я верю, что он работает, но... почему?)
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
15.02.2014, 16:17
Лучший ответ Сообщение было отмечено Rammal как решение

Решение

Rammal, дело в том, что в словаре хранятся KeyValuePair<TKey,TValue>. Поэтому когда вы делаете присваивание, то вы получаете копию значения, хранящегося по этому ключу, а не ссылку на это значение. Поэтому вот этот код все равно выведет 12345, даже если в словаре пусто:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
 
namespace ConsoleApplication123
{
    class Page
    {
        public string textPage;
        public Page(string newText)
        {
            textPage = newText;
        }
    }
 
    class Book
    {
        public Dictionary<string, Page> pages = new Dictionary<string, Page>();
    }
 
 
    class Program
    {
        private static void Main(string[] args)
        {
            Page firstPage = new Page("12345");
            Book book = new Book();
            book.pages.Add("page1", firstPage);
 
            var myPage = book.pages["page1"];
 
            Page secondPage = new Page("67890");
            book.pages["page1"] = secondPage;
            
            book.pages = null;
            Console.WriteLine(myPage.textPage);
        }
    }
}
мы обнулили словарь, но при попытке доступа к этому элементу вместо ошибки все сработает. А почему? А потому что копию смотрим.

А в моем случае мы всегда пытаемся достать из словаря и если его обнулить, получим ошибку.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.02.2014, 16:17
Помогаю со студенческими работами здесь

Как построить класс так чтобы при изменении одного из свойств, класса создавался новый поток?
Добрый всем день. Помогите разобраться с задачей. Задача: Создайте класс Bank в котором будут следующие свойства: int money,...

Как сделать так, чтобы был один string на весь класс?
Доброго времени суток. Я хотел бы узнать, есть ли какой-нибудь метод, который дал бы написать один раз string и в последующем коде...

Как сделать так чтобы переменная была доступна из другого класса, метода?
как сделать так чтобы переменная была доступна из другого класса, метода?

Как сделать чтобы из первого класса вычитал второй и третий класс?
Как сделать чтобы из первого класса вычитал второй и третий класс? #include &lt;iostream&gt; using namespace std; class shaiba { ...

Определить функцию-член в наследнике так, чтобы её можно было вызвать только по ссылке на базовый класс
Пусть дан абстрактный класс A class A { public: void virtual method() const = 0; }; Определите класс B - наследник от...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru