Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Как правильно сохранить? Добавлено: 11.09.04 13:45  

Автор вопроса:  danser | ICQ: 299287824 
Dim T As New ArrayList()
Dim Str As String = "Sasha"
Dim Arr As New ArrayList()
Arr.Add(Str & Str)
T.Add(Str)
T.Add(Arr)

Dim B As New ArrayList()
B = CType(T.Clone, ArrayList)


Dim C As New ArrayList()
C.Add(B)

'теперь изменим масив Т
T.Item(0) = "Wasa"
CType(T.Item(1), ArrayList).Item(0) = "None"

With CType(C.Item(0), ArrayList)
 MsgBox(CType(.Item(0), String))
 '= "Saha"
MsgBox(CType(CType(.Item(1), ArrayList).Item(0), String))
 '= "None"
End With

С етого кода можно увидеть что при изменении елементов масива Т изменяются по разному значения елементов масива С:
                -Если мы изменим первый елемент(строку) масива Т->(T.Item(0) = "Wasa"), то это не отобразится на первом елементе(строке) масива С;
но стоить нам изменить второй елемент масива Т(тоже масив в котором мы изменим первый его елемент -> (CType(T.Item(1), ArrayList).Item(0) = "None")) то второй елемент масива С тоже будет изменен
                ВОПРОС: Как присвоить масиву В масив Т так что би при последуещем изменении масива Т масив B(и соответственно масив С) не изменялся:
ТОБИШЬ должно быть:
        With CType(C.Item(0), ArrayList)
            MsgBox(CType(.Item(0), String))
            '= "Saha"
            MsgBox(CType(CType(.Item(1), ArrayList).Item(0), String))
            '= "SashaSasha"
        End With
        Заранее благодарен за предположения по этому поводу.

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #1
Добавлено: 12.09.04 07:17
А зачем нужен такой гемморой с кучей ArrayList'ов?

> то второй елемент масива С тоже будет изменен
Судя по коду, в объекте C только 1 элемент:

Dim C As New ArrayList()
C.Add(B)

Откуда там может взяться второй?


P.S. Некорректно называть ArrayList массивом. Массив - это класс
Array, объявляется массив примерно так:

Dim b(25) As String

А ArrayList - это коллекция.

Ответить

Номер ответа: 2
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #2 Добавлено: 12.09.04 11:39
Этот геморой нужен для обяснения проблемы, в чистом виде этот код не используется.

> то второй елемент масива С тоже будет изменен
-Имелось ввиду первый(запутаешся со словами, в коде более понятно)

Как сохранить обект Т в колекции С, чтобы при последуещем изменеии обекта Т эти изменеия не касались обекта сохраненного в колекции С?
Предложен вариант:
B=Ctype(T.Clone, ArrayList)
C.Add(B)
В примере видно что в одном случае это помагает но к сожалению только в одном...

Ответить

Номер ответа: 3
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #3
Добавлено: 12.09.04 16:35
Как показало изучение потрохов ArrayList, метод Clone действует вполне
корректно:

'System.Collections.ArrayList.Clone
Public Overridable Function Clone() As Object Implements System.ICloneable.Clone
Dim _arrayList As System.Collections.ArrayList = New System.Collections.ArrayList(_size)
_arrayList._size = _size
_arrayList._version = _version
System.Array.Copy(_items, 0, _arrayList._items, 0, _size)
Return _arrayList
End Function

Он делает полную копию исходного объекта, копируя элементы из
внутреннего массива.

Далее... Если Вы меняете ссылку на объект в элементе коллекции, то на
исходном оъекте T это никак сказаться не должно:

T = New ArrayList
T.Add "a"
B=Ctype(T.Clone, ArrayList)
B(0) = "b"
Console.WriteLine T(0)

Но если меняется, к примеру, поле объекта-элемента, то эти изменения
будут видны в объекте T, так как метод Clone не создает копии
ссылочных элементов коллекции.

Public Class Test
Public a As String
End Class

'...

T = New ArrayList
Dim test As New Test
test.a = "a"
T.Add test
B=Ctype(T.Clone, ArrayList)
B(0).a = "b"
Console.WriteLine T(0).a


Вы это имели в виду?

Ответить

Номер ответа: 4
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #4 Добавлено: 12.09.04 17:48
Да мы это имели ввиду... только немножко измени(изменяется обект Т):
B=Ctype(T.Clone, ArrayList)
T(0).a = "b"
Console.WriteLine B(0).a

Как я понял ссылочние елементи колекции это всякого рода структуры (ArrayList, Structure, пользовательськие обекти...) и на ети елменти-обекты в колекции находятся только ссылки...
Но что мне делать если надо зафиксировать колекцию Т(и все ее елементы-обекти)?

Ответить

Номер ответа: 5
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #5
Добавлено: 13.09.04 08:57
Можно для каждого элемента отдельно создавать копию:

Dim B As New ArrayList

For Each obj As Object In T
CType(B, IClonable).Add obj.Clone
Next

Тут только нужно повнимательнее рассмотреть вариант, если элемент
коллекции не реализует или неправильно реализует интерфейс IClonable.

Ответить

Номер ответа: 6
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #6 Добавлено: 13.09.04 09:28
Это вариант только одчасти решает проблему, я думал о нем, но если елементи обекты из колекци имеют довольно сложную структуру(в примере обект Тest имеет не одно поле типа String, а поле типа <Пользовательський обект> которий в совю очередь тоже имеет поле <Пользовательський обект> и так несколько раз) что тогда делать?

Ответить

Номер ответа: 7
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #7
Добавлено: 13.09.04 09:50
Если все классы в этой структуре имеют атрибут Serializable, то можно
сериализовать и десериализовать объект. Тогда будет создана автономная
точная копия данных.

Ответить

Номер ответа: 8
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #8 Добавлено: 13.09.04 12:43
Да класи сереализированы. Это нужно для последуещего сохранения обекта в файле.
Но вроде метод Serializable должен иметь в аргументе обект типа FileStream которий в свою очередь связан с физическим файлом...предлагаешь использовать физический файл?...
как сохранить в другой(конкретного типа например Test) структуре(по возможности без использования физического файла)?

Ответить

Номер ответа: 9
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #9
Добавлено: 13.09.04 14:01
Используй MemoryStream.

Ответить

Номер ответа: 10
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #10 Добавлено: 13.09.04 16:31
Какая ошибка?
До этого не пробывал работать с класом MemoryStream.
Чем инициализировать этот обект(MSDN нету- неоткуда пример постмотреть)?
dim T as new TSeansStatistic
...
Dim saveFile As MemoryStream
Dim BFormatter As New BinaryFormatter()
BFormatter.Serialize(saveFile, T)
Items_.Add(CType(BFormatter.Deserialize(saveFile), TSeansStatistic))
saveFile.Close

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: End of Stream encountered before parsing was completed.

Если знаешь подкинь пожайлуста какой в этом случае должен быть код или пример с MSDN по MemoryStream.

Ответить

Номер ответа: 11
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #11 Добавлено: 13.09.04 16:33
Уточню: такая ошыбка для-
Dim saveFile As New MemoryStream()

Ответить

Номер ответа: 12
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #12
Добавлено: 13.09.04 16:52
Мммммм.. У меня таких проблем не возникала.. Сейчас поищу кусок
рабочего кода из своих проектов...

Dim Stream As New IO.MemoryStream()
Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
formatter.Serialize(Stream, Errors)

Далее передвигаем позиию стрима в начало и десериализуем объект из
того же стрима. После этого стрим можно закрыть.




Ответить

Номер ответа: 13
Автор ответа:
 danser



ICQ: 299287824 

Вопросов: 76
Ответов: 209
 Профиль | | #13 Добавлено: 13.09.04 18:43
Да все так как ты говоришь- не передвинул позицию в начало..., а так все вроде получилось, сохраняет всю структуру что и требовалось доказать :) спасибо Павел что помог..., а то не знаю что бы я делал...

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам