![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как в delphi получить копию экземпляра класса?
sdsk © (2009-08-14 14:51:00)Давно не писал в Delphi. Напомните как это делается?
Kolan (2009-08-15 23:18:00) [1]Jonh, не обещаю, что попробую. Если бы вы дали такой пример, чтобы вставил-запустил-написал на форуме, то я бы проверил в Дельфи 2006-2007-2009
Jonh (2009-08-15 19:21:00) [2]
> Kolan © (15.08.09 00:06) [18]
модуль не сохранился, метод выглядел приблизительно так:
procedure TObjectHelper.LoadFromXML(const Node: IXMLNode; SomeEvent: TSomeEvent);
(попытка сделать реализацию сохранения\загрузки на основе RTTI)
Не исключено, что это уже исправили - проверьте, если не трудно (у меня под рукой нет Delphi), второй параметр - метод
при входе в тело LoadFromXML параметр Node указывал не на то, что передали
Kolan (2009-08-15 00:06:00) [3]Jonh, закинте пример, интересно проверить в разных версия Делфи.
Jonh (2009-08-14 23:50:00) [4]
> Как вариант можно написать класс-хелпер для TObject'а где
> и сделать соответствующую функцию.
Пробовал делать хелпер для TObject, наткнулся на ошибки при компиляции. То есть все компилируется, но неправильно (при входе в тело метода хелпера теряются параметры), победить так и не сумели, пришлось от этой затеи отказаться
Kolan (2009-08-14 16:34:00) [5]Я бы не стал, даже если бы это было возможно, делать простое копирование в предке и оставлять сложности на потомков. Потом хрен найдешь где что отвалилось.
Есть стандартный механизм сAssignего нужно использовать везде где есть хоть малейшие сложности. А в хелпере я бы сделал методSimpleClone, который бы и вызывал, отдавая себе отчет, для тех классов, которые представляют из себя простые контейнеры.
Хотя я, лично, всегда пишу ручное копирование, а в раздел, где объявлены поля вставляю комментарий, чтобы не забывать дописыватьAssign, если набор полей изменится.
sdsk (2009-08-14 16:24:00) [6]
> Kolan © (14.08.09 16:12) [14]
> Все-таки иногда было бы удобно, чтобы метод, реализующий
> неглубокое копирование был уже в классе. Я, например, сходу
> не напишу копирование объекта путем копирования памяти,
> а вот вызвать метод, понимая что он делает мне под силу.
>
>
> Как вариант можно написать класс-хелпер для TObject'а где
> и сделать соответствующую функцию.
Я тоже подумывал над этим. Правда делфиские хелперы отстают от нетовских Extensions Methods. Могут быть сложности с кодингом. И будут неоднозначные ситуации, которые сложно решать на уровне предка. Но если предок возьмет на себя хотябы часть работы, это уже будет неплохо
Kolan (2009-08-14 16:12:00) [7]Все-таки иногда было бы удобно, чтобы метод, реализующий неглубокое копирование был уже в классе. Я, например, сходу не напишу копирование объекта путем копирования памяти, а вот вызвать метод, понимая что он делает мне под силу.
Как вариант можно написать класс-хелпер для TObject'а где и сделать соответствующую функцию.
sdsk (2009-08-14 16:05:00) [8]согласен :)
Юрий Зотов (2009-08-14 16:02:00) [9]> sdsk © (14.08.09 15:55) [11]
> в .NET этот метод гарантирован интерфейсом ICloneable
Как и в Java.
> в Delphi же метод просто виртуальный. Соответственно нет никаких
> гарантий, что один из предков не нарушил последовательность
> клонирования.
Верно, таких гарантий нет. Но и в .Net, и в Java тоже нет гарантий что разработчик класса-предка написал метод Clone правильно. В итоге получим то же самое.
sdsk (2009-08-14 15:55:00) [10]Только есть одно отличие в .NET этот метод гарантирован интерфейсом ICloneable в Delphi же метод просто виртуальный. Соответственно нет никаких гарантий, что один из предков не нарушил последовательность клонирования. Но это правда не существенное отличие. В остальном алгоритм примерно схож
Юрий Зотов (2009-08-14 15:52:00) [11]> sdsk © (14.08.09 15:39) [8]
> В .NET данная задача решается с помощью механизма клонирования.
И в Java тоже. Однако же, метод Clone пишет программист, разработчик класса - и как он этот метод реализовал, такую копию и получим. По умолчанию же выполняется неглубокое клонирование (что бывает опасно, потому что класс может содержать ссылки).
Аналогично и в Delphi. Неглубокое клонирование можно выполнить простым копированием памяти (что тоже опасно и по той же самой причине), а для глубокого служит метод Assign. Это аналог метода Clone, его тоже пишет разработчик класса и как он этот метод реализовал - такую копию и получим.
То есть, имеем практически полную аналогию. Чего, собственно, и следовало ожидать.
Медвежонок Пятачок (2009-08-14 15:40:00) [12]ну закопируй например датасет если все так просто выглядит
sdsk (2009-08-14 15:39:00) [13]>Palladin ©
Уважаемый, не зазнавайтесь. Ушел из delphi еще несколько лет назад на C#. В .NET данная задача решается с помощью механизма клонирования. Вот и возник вопрос есть ли что-либо подобное в Delphi.
> Anatoly Podgoretsky © (14.08.09 15:25) [5]
> > sdsk (14.08.2009 15:19:03) [3]
>
> А что именно скопировать то, ты видимо представляешь класс,
> как последовательность байтов, а это не так, поскольку
> есть ссылочные типы, при том возможно циклические. Лучший
> путь поэлементное копирование, но и оно не всегда достаточно.
>
Сложности понимаю. Но и ссылочные типы также можно рекурсионно клонировать. В процессе этой операции множество нюансов, но все они технически решаемы.
Palladin (2009-08-14 15:29:00) [14]Раз в пол года приходят вот такие вот человеческие "экземпляры давно не писавших в делфи" (то бишь вообще ничего не знающих) и начинают выступать. "Ну как так такого простого нет", сами понятия не имеют чего такое это самое "такое".
Дмитрий Белькевич (2009-08-14 15:26:00) [15]
> Неужели в delphi нет способа скопировать экземпляр на низком
> уровне?
Как ты себе это представляешь? В частности копирование динамических объектов/структур?
Anatoly Podgoretsky (2009-08-14 15:25:00) [16]> sdsk (14.08.2009 15:19:03) [3]
А что именно скопировать то, ты видимо представляешь класс, как последовательность байтов, а это не так, поскольку есть ссылочные типы, при том возможно циклические. Лучший путь поэлементное копирование, но и оно не всегда достаточно.
Palladin (2009-08-14 15:24:00) [17]А что такое "копия экземпляра" ?
sdsk (2009-08-14 15:19:00) [18]Анатолий, внимательно вопрос прочтите. Я спрашивал как создать КОПИЮ ЭКЗЕМПЛЯРА класса, а не как создать экземпляр.
> Amoeba © (14.08.09 15:05) [1]
> Если класс - потомок TPersistent - то с помощью метода Assign.
> Иначе - ручками.
Это довольно нестабильный подход. Assign определен в TPersistent как виртуальный. Каждый наследующий класс должен самостоятельно реализовывать нюансы по своему копированию. Если он это не делает, то мы получим только частичную копию.
Неужели в delphi нет способа скопировать экземпляр на низком уровне?
Anatoly Podgoretsky (2009-08-14 15:12:00) [19]> sdsk (14.08.2009 14:51:00) [0]
Obj := TClass.Create
Amoeba (2009-08-14 15:05:00) [20]Если класс - потомок TPersistent - то с помощью метода Assign. Иначе - ручками.