Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.07.21;
Скачать: CL | DM;

Вниз

TList<TRecord>   Найти похожие ветки 

 
Дмитрий С ©   (2013-02-26 22:26) [0]

Есть тип
TRecord = record
SomeField: String;
end;

Есть
A: TList<TRecord>;

Делаю A[I].SomeField := "Foo", одна запись в списке не получает этого значения (его получает скорее всего копия).
Вопрос, как сделать, чтобы получала?


 
clickmaker ©   (2013-02-26 22:48) [1]

> Делаю A[I].SomeField := "Foo", одна запись в списке не получает
> этого значения (его получает скорее всего копия).

это как?


 
Jeer ©   (2013-02-26 23:31) [2]


> Вопрос, как сделать, чтобы получала?


Загадочный ты, парень.
Даже не знаю, кто бы тебя взял в разведку :(


 
Rouse_ ©   (2013-02-26 23:33) [3]


> одна запись в списке не получает этого значения

так и говорит - я не получила?


 
Дмитрий С ©   (2013-02-26 23:45) [4]


> так и говорит - я не получила?

Поле остается пустым после присвоения.


 
знайка   (2013-02-26 23:48) [5]

А копия откуда взялась?


 
Rouse_ ©   (2013-02-26 23:49) [6]

Код давай


 
Дмитрий С ©   (2013-02-26 23:51) [7]

Вот пример:


program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
 System.SysUtils, Generics.Collections;

type
 TRecord = record
 private
   FField: String;
   procedure SetField(const Value: String);
 public
   property Field: String read FField write SetField;
 end;

var
 Rec: TRecord;
 List: TList<TRecord>;

{ TRecord }

procedure TRecord.SetField(const Value: String);
begin
 FField := Value;
end;

begin
 try
   List := TList<TRecord>.Create;
   try
     Rec.Field := "Foo";
     List.Add(Rec);
     List[0].Field := "Bar";
     Writeln(List[0].Field); // Foo
   finally
     List.Free;
   end;
 except
   on E: Exception do
     Writeln(E.ClassName, ": ", E.Message);
 end;
 readln;
end.



 
Игорь Шевченко ©   (2013-02-27 00:04) [8]

http://clubs.ya.ru/4611686018427388044/replies.xml?item_no=1154


 
Дмитрий С ©   (2013-02-27 00:06) [9]


> Игорь Шевченко ©   (27.02.13 00:04) [8]

У TList<T> массив с элементами находится в секции private, поэтому получить указать не запись нет возможности. Разве что только скопировать определение TList<T>.


 
Игорь Шевченко ©   (2013-02-27 00:09) [10]

Дмитрий С ©   (27.02.13 00:06) [9]

   Rec := List[0];
   Rec.Field := "Bar";
   List[0] := Rec;


 
знайка   (2013-02-27 00:15) [11]

это value тип, с ним так нельзя, вот и копия.


 
Jeer ©   (2013-02-27 00:15) [12]


> Игорь Шевченко ©   (27.02.13 00:09) [10]


А, казалось бы, элементарщина :)


 
clickmaker ©   (2013-02-27 00:20) [13]

TRecord = class


 
Дмитрий С ©   (2013-02-27 00:44) [14]


> TRecord = class

Похоже так и придется. Не понятен тогда тайный смысл TList<T>-а


 
bems ©   (2013-02-27 06:35) [15]


> Не понятен тогда тайный смысл TList<T>-а

про зеркало и рожу слыхал? сам TList<T> тут собственно и не причем, этот вопрос возникает всегда когда есть свойство типа запись, доступное на запись (не обязательно дефолтное и не обязательно связанное с дженериками). и тебе показали правильный выход из ситации

>    Rec := List[0];
>    Rec.Field := "Bar";
>    List[0] := Rec;


 
bems ©   (2013-02-27 06:37) [16]


> доступное на запись

через метод-сеттер, конечно-же


 
брат Птибурдукова   (2013-02-27 08:40) [17]


> про зеркало и рожу слыхал?
+1


 
знайка   (2013-02-27 09:43) [18]

а с# уже на строку  List[0].Field = "Bar"; ругается и не пропускает её.


 
clickmaker ©   (2013-02-27 11:28) [19]

> List[0].Field = "Bar"

D2009 ее подчеркивает, пишет что-то типа "List does not contain field "Field"", но при этом пропускает


 
Дмитрий С ©   (2013-02-27 12:04) [20]

Могли хотя бы доступ к массиву сделать protected, что бы иметь указатель на запись.


> бе показали правильный выход из ситации
>

Рабочий способ, но чтобы правильный - не думаю. Правильно будет не использовать рекорды в тлист.


 
jack128 ©   (2013-02-27 12:08) [21]


> Правильно будет не использовать рекорды в тлист.

правильным будет либо плюсовый подход(там vector[] вернет ссылку на запись, и твой исходный код будет работать как ожидается), либо шарповский подход, где будет ошибка компиляции.


 
DevilDevil ©   (2013-02-27 12:13) [22]

офтоп:

чёт меня Delphi не радует своими нововведениями


 
jack128_   (2013-02-27 13:39) [23]


> чёт меня Delphi не радует своими нововведениями

чем плохи нововведения?


 
DevilDevil ©   (2013-02-27 15:33) [24]

> чем плохи нововведения?

тем что вектор не сделали
и ещё были какие-то проблемы со структурами

http://delphimaster.net/view/15-1360736756/
смотри пост [33]


 
Дмитрий С ©   (2013-02-27 15:51) [25]


> Игорь Шевченко ©   (27.02.13 00:09) [10]
> Дмитрий С ©   (27.02.13 00:06) [9]
>
>    Rec := List[0];
>    Rec.Field := "Bar";
>    List[0] := Rec;

А вы у себя на работе так делаете (позволяете делать)?


 
jack128_   (2013-03-01 14:44) [26]


> тем что вектор не сделали

для этого нужны ссылки.

> и ещё были какие-то проблемы со структурами

вот эта проблема выеденного яйца не стоит. Два символа удалить лень..

и ни тот, ни другой аргумент не имеют отношения к нововведениям языка.

А вот вопрос топик стартера - имеет. Только там проблема не в дженерик листе, а в методах у рекорда. Если для свойства Field убрать сеттер, то код [7] перестанет компилироваться. Собственно проблема в отсутствии признака константности у методов. в результате - компилятор позволяет вызывать _любые_ методы у рекорда.
Я так понимаю касяк в [7] - это частный случай вот такого косяка:

procedure DoWork(const R: TRecord);
begin
 R.Field := "2121"; // вполне нормально компилируется. Хотя R -типа как cosnt
end;


 
Дмитрий С ©   (2013-03-01 14:49) [27]

Проблема решилась:


 TTextList = class(TList<TText>)
 private
   function GetText(I: Integer): PText;
 public
   property Text[I: Integer]:PText read GetText; default;
 end;

function TTextList.GetText(I: Integer): PText;
begin
 Result := @FItems[i];
end;


Почему компилятор разрешил обратится к приватному члену я не знаю.


 
Игорь Шевченко ©   (2013-03-01 14:53) [28]


> Проблема решилась:


"Кривое не может сделаться прямым" (Еккл. 1, 15)


 
jack128_   (2013-03-01 14:54) [29]


> Почему компилятор разрешил обратится к приватному члену
> я не знаю.

а где у тебя обращение к приватному полю?


 
jack128_   (2013-03-01 14:55) [30]


> Если для свойства Field убрать сеттер

в смысле - вместо сеттера запись прямо в поле сделать:
property Field: stirng read FField write FField;


 
Дмитрий С ©   (2013-03-01 14:56) [31]


> а где у тебя обращение к приватному полю?

FItems приватный.


TList<T> = class(TEnumerable<T>)
 private
 type
   arrayofT = array of T;
 var
   FItems: arrayofT;
   FCount: Integer;
   FComparer: IComparer<T>;



> Игорь Шевченко ©   (01.03.13 14:53) [28]

А что вам не нравится в передачи записи по ссылке?


 
jack128_   (2013-03-01 15:00) [32]


> FItems приватный.

у мя на d2010 твой код выдает internal error

[DCC Fatal Error] Unit1.pas(45): F2084 Internal Error: AV21F66973-R00000000-0


 
Игорь Шевченко ©   (2013-03-01 15:07) [33]


> А что вам не нравится


как минимум, не нравится смешение типов в одном объявлении


>  TTextList = class(TList<TText>)
>  private
>    function GetText(I: Integer): PText;
>  public
>    property Text[I: Integer]:PText read GetText; default;
>
>  end;


 
Дмитрий С ©   (2013-03-01 15:12) [34]


> Игорь Шевченко ©   (01.03.13 15:07) [33]

Понятно. А какой выход?
такой?
  Rec := List[0];
  Rec.Field := "Bar";
  List[0] := Rec;



 
Плохиш ©   (2013-03-01 15:19) [35]


> Почему компилятор разрешил обратится к приватному члену
> я не знаю.

Описания обоих классов находятся в одном pas-файле.


 
Дмитрий С ©   (2013-03-01 15:27) [36]


> Описания обоих классов находятся в одном pas-файле.

Нет.


 
Игорь Шевченко ©   (2013-03-01 16:02) [37]


> А какой выход?


зависит от задачи


 
clickmaker ©   (2013-03-01 16:20) [38]

> [27] Дмитрий С ©   (01.03.13 14:49)
> Проблема решилась:

а зачем так сложно? чем класс не устраивает?



Страницы: 1 вся ветка

Текущий архив: 2013.07.21;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.007 c
2-1353827595
ДенисПФ
2012-11-25 11:13
2013.07.21
Packed Record to MemoryStream


3-1291201543
StriderMan
2010-12-01 14:05
2013.07.21
isc_shutinprog


15-1362120707
Дмитрий С2
2013-03-01 10:51
2013.07.21
Восстановление Raid0


15-1362067551
Ega23
2013-02-28 20:05
2013.07.21
А почему над картошкой дышат?


15-1361990175
ХХХХХ
2013-02-27 22:36
2013.07.21
Как сделать паузу?