Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
Есть код:
У объекта есть метод Copy() который создаёт копию объекта. Копия ни как не должна быть связана с первоначальным объектом. Т.е. изменение копии не должно повлиять на первоначальный объект. Между народом возникли разногласия. Некоторые говорят, что надо делать не Name = Name непременно Name = string.Copy(Name). Теоретически, b.Name - это ведь ссылка на строку. Значит, можно изменить сроку без изменения ссылки. Другие говорят - нет такого кода, который можно поставить вместо b.Name="2", что бы вывелось 1. Какие будут мнения? Кто прав? |
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
Тут есть про глубокое и поверхностное клонирование.
docs.microsoft.com При этом использование данного метода здорово упрощает и сокаращает код - уже не надо в своём методе копирования (если оно должно быть "глубоким") перечислять все 100500 свойств объекта - достаточно озаботится созданием "настоящих копий" лишь для свойств ссылочных типов. И хотя в примере применяют String.Copy(Name) это действие на 99% бессмысленное. Да, между string newString = oldString; и string newString = String.Copy(oldString); есть разница - она проявится при использовании метода ReferenceEquals. Ну и ещё (теоретически) при использовании небезопасного кода - по идее там можно поменять содержимое строки не поменяв саму ссылку на неё (ну и, конечно, если залезть непосредственно в память дотнет-процесса то тоже можно поменять содержимое строки). Правда за такие выкрутасы надо бить по голове автора до просветления Это нарушает сам принцип неизменности дотнетовских строк (строка хоть и сылочный тип, но ведёт себя во многом как value тип). Ну и в современной версии CLR метод String.Copy помечен как Obsolete - так что использовать его всё же не следует. Кстати, есть штатный интерфейс ICloneable с методом Clone предназначенный именно для целей созданий копий - при этом НЕ регламентируется какую именно копию будет создавать каждая конкретная реализация - глубокую, поверхностную или что-то среднее (ну там одни типы или даже просто свойства "глубоко" копировать, а другие - брать ссылку на исходный объект). Правда мануал не рекомендует использовать этот интерфейс в качестве публичного (т.е. не стоит его объявлять и соответственно реализовывать для публично видимых объектов - именно по причине неопределённости поведения). Кроме того он несколько неудобен, т.к. возвращает всегда object - т.е. потребуется приведение типа. Если уж есть большая нужда (во многих типах) в унифицированной операции копирования, то лучше свой generic интерфейс описать и его и реализовывать. ------------------ WBR, Igor |
Re: Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
Т.е. из Managed кода изменить строку не получится. |
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
Тут речь идёт про небезопасный код, а не про неуправляемый.
Старая, но полезная статья. habr.com ------------------ WBR, Igor |
Re: Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
Т.е. из unsafe кода таки можно. Спасибо.
|
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
"Можно" в смысле технической возможности - но если у вас есть идиот странный человек который так будет делать без ну очень веской причины (я таковую сходу придумать не могу - тем более для бизнес-объектов, не в части взаимодействия со всякими неуправляемыми кодами, низкоуровневыми системными АПИ, и т.п.), то лучше сразу гнать взашей Соответственно строить всю логику исходя из того что кто-то там сделает этакое - неправильно. Тем более что незапланированное "синхронное" изменение содержимого строкового поля в объекте-копии, это просто детский лепет по сравнению с другими весёлостями которые ожидают, если таки нарушить принцип неизменности значений строкового типа. Принцип этот чётко прописан в мануалах, и адекватный разработчик в общем то не будет подозревать что кто-то в здравом уме станет его нарушать Тем паче что даже сами разработчики системы пометили String.Copy как устаревший, и поправили все те места в CLR где это использовалось
------------------ WBR, Igor |
Re: Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
В настоящий момент в проекте unsafe не встречается. Так что, опасности нет. Если кто то попытается вставить в код unsafe, ему придётся объяснять - зачем (как говорят индейцы, магическое слово НАХУА).
|
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
Тут дело даже не в unsafe как таковом - его использование то не вызывает вопросов, а в том зачем из строки, прописанной во всех мануалах как неизменная сущность, делать изменяемую сущность Ну это как хакнуть рантайм чтобы false стало истинным, а true ложным
------------------ WBR, Igor |
Re: Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
Первоначальный спор между коллегами был на тему:
в public Test Copy() нужен ли Name = string.Copy(Name) или достаточно Name = Name. Судя по тому, что без unsafe изменить b.Name не удастся, достаточно Name = Name. Но, если бы мы писали какую то библиотеку (и не имели бы контроля надо кодом, который использует b.Name, string.Copy нужен. Исправлено 1 раз(а). Последнее : S-type, 06.06.19 08:10 |
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
Не нужен уже хотя бы потому что это obsolete метод в текущей версии. Сами разработчики CLR от него избавляются.
А сколько "веселья" можно получить если начать изменять значения в объектах string... Тривиальнейший пример даже в мануале есть:
------------------ WBR, Igor |
Re: Копирование | |
---|---|
S-type Сообщений: 2969 Дата регистрации: 24.04.2004 |
М, да... Т.е. компилятор экономит память - собирает литералы "в кучку", меняем один - меняется другой. Просто звездец.
|
Re: Копирование | |
---|---|
Igor Korolyov Автор Сообщений: 34580 Дата регистрации: 28.05.2002 |
Звиздец это не уча матчасть "лепить горбатого" - в т.ч. делать из string "изменяемый" тип, ну или "предполагать" что string это изменяемый тип и "защищаться" путём клонирования строк (так то и шпагу глотать можно - но успешно это может проделать лишь 1 из 100000 человек ). А интернирование строк - полезный и хорошо документированный механизм, он и в рантайме доступен, не только для строковых литералов (т.е. при компиляции).
------------------ WBR, Igor |
© 2000-2024 Fox Club  |