Форум: "Прочее";
Текущий архив: 2013.07.21;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.003 c