Методы в struct
От: Andrew-K-N  
Дата: 23.02.03 03:27
Оценка:
Здравствуйте! Помогите понять в чем ошибка!

Есть интерфейс

public interface ISerialize
{
   void Write(BynaryWriter bw);
   void Read(BynaryReader br);
}


и определена структура

public struct Point:ISerialize
{
   public int x;
   public int y;
   ...
   ...
   void ISerialize.Write(BynaryWriter bw)
   {
      bw.Write(this.x);
      bw.Write(this.y);
      ...
   }
   void ISerialize.Read(BynaryReader br)
   {
      this.x=br.ReadInt32();
      ...
   }
}


есть класс, содержащий массив этой структуры,
и также реализующий интерфейс ISerialize
Вот пример кода

...
private Point[] mass;

...
void ISerialize.Read(BynaryReader br)
{
   for(int i=0;i<mass.Length;i++)
      {
         ((ISerialize)mass[i]).Read(br);// 1  
      }
   ...
}
...



в строке, помеченой 1, элемент массива после завершения метода остается
с нулевыми значениями, хотя метод Read в структуре считывает значения из потока
и присваивает их полям, но по возвращении — поля пустые (0 и null)

Помогите, пожайлуста!
Re: Методы в struct
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.02.03 07:17
Оценка:
Здравствуйте, Andrew-K-N, Вы писали:

AKN>Есть интерфейс


AKN>
AKN>public interface ISerialize

А чем стандартный ISerializable не покатил?

AKN>есть класс, содержащий массив этой структуры, 
AKN>и также реализующий интерфейс ISerialize
AKN>Вот пример кода

AKN>         ((ISerialize)mass[i]).Read(br);// 1  
AKN>в строке, помеченой 1, элемент массива после завершения метода остается
AKN>с нулевыми значениями, хотя метод Read в структуре считывает значения из потока
AKN>и присваивает их полям, но по возвращении - поля пустые (0 и null) :xz: 

Все так и должно быть. Когда ты преобразовываешь структуру к ISerialize то происходит боксинг этой структуры и создание ее копии внутри бокс-класса. Поэтому чтение происходит в эту копию, которая затем просто пропадает. А в массиве остается старое значение. Помочь твоей беде можно например так

[c#]
ISerialize s = (ISerialize) mass[i]; //Получаем боксированную копию
s.Read(br); //Заполняем копию
mass[i] = s; //Делаем анбоксинг в массив
... << RSDN@Home 1.0 beta 6 (np: тихо) >>
AVK Blog
Re: Методы в struct
От: TK Лес кывт.рф
Дата: 23.02.03 07:18
Оценка:
"Andrew-K-N" wrote...
>
> Есть интерфейс
>
>
> public interface ISerialize
> {
>    void Write(BynaryWriter bw);
>    void Read(BynaryReader br);
> }
>

>
> и определена структура
>
>
> public struct Point:ISerialize
> {
> }
> ...
>

>
>
> в строке, помеченой 1, элемент массива после завершения метода остается
> с нулевыми значениями, хотя метод Read в структуре считывает значения из потока
> и присваивает их полям, но по возвращении — поля пустые (0 и null)
>
Это типичный пример использования box/unbox. В данном случае он происходит в строке ((ISerialize)mass[i]).Read(br);
т.е. существующий объект куда-то копирует и на копии вызывается Read. Именно по этому структуры настоятельно рекомендуется делать Immutable
Posted via RSDN NNTP Server 1.4.6 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Методы в struct
От: MaxMP Россия  
Дата: 23.02.03 13:07
Оценка:
В данном случае, если не приводить к интерфейсу, боксинга не будет и все заработает как надо.

Т.е. достаточно:
void ISerialize.Read(BynaryReader br)
{
   for(int i=0;i<mass.Length;i++)
      {
         mass[i].Read(br);
      }
   ...
}
Re[3]: Методы в struct
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.02.03 13:16
Оценка:
Здравствуйте, MaxMP, Вы писали:

MMP>В данном случае, если не приводить к интерфейсу, боксинга не будет и все заработает как надо.


MMP>Т.е. достаточно:


Обрати внимание на это
void ISerialize.Read(BynaryReader br)

Так что не будет
... << RSDN@Home 1.0 beta 6 (np: тихо) >>
AVK Blog
Re[4]: Методы в struct
От: MaxMP Россия  
Дата: 23.02.03 13:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Обрати внимание на это

AVK>void ISerialize.Read(BynaryReader br)

AVK>Так что не будет


А, ну да, от explicit interface implementation в структуре придется отказаться (она там, как мы видим, только вредит).
Re[4]: Методы в struct
От: Igor Trofimov  
Дата: 23.02.03 13:29
Оценка:
AVK>Обрати внимание на это
AVK>void ISerialize.Read(BynaryReader br)
AVK>Так что не будет

Да. Но есть подозрение, что человеку сгодится и просто

void Read(BynaryReader br)


И тогда все-таки будет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.