строки и mem'ы
BEGIN
form1.MemoDBG.Lines.Add(s);
END;
procedure dbgn(n:longint);
BEGIN
form1.MemoDBG.Lines.Add(inttostr(n));
END;
procedure dbgm(s:Tstrings);
var i:word;
BEGIN
form1.MemoDBG.Lines.Add('memo#');
for i:=0 to s.Count-1
do form1.MemoDBG.Lines.Add(inttostr(i)+'#'+s.strings+'#');
END;
ВОПРОС: почему №1 и №2 в memoDBG выводят разные значения?
и как с этим бороться?
slovtoNew(i); dbgs('sub=');dbgm(sub); //№2
где
sub:Tstrings;//я знаю, что лучше писать TstringList, но поскольку все lines
у mem'ов типа Tstrings, для большей совместимости Tstrings
a slovtoNew(i); изменяет memonew.lines
PS: чем отличается lines от lines.strings?
Lines от Lines.Strings ничем не отличается - это довольно свежая фича, для повышения удобочитаемости.
Зы. Почитайте стандарты оформления кода Дельфи - Ваш код весьма уныл.
а что Вам конкретно не понравилось в моем коде, я нашел только:
- большие BEGIN и END, но я их делаю большими только в начале и в конце процедур и функций - для отделения описаний от кода
- пробелы после двоеточий не ставлю - виноват
- memoDBG и три отладочных функции можно было бы объявить как новый класс, но я совсем недавно пересел с паскаля на делфи и в ООП еще не силен
begin
form1.MemoDBG.Lines.Add(s);
end;
procedure dbgn(n : longint);
begin
form1.MemoDBG.Lines.Add(inttostr(n));
end;
procedure dbgm(s : Tstrings);
var
i : word;
begin
form1.MemoDBG.Lines.Add('memo#');
for i := 0 to s.Count - 1 do
form1.MemoDBG.Lines.Add(inttostr(i) + '#' + s.strings + '#');
end;
...
sub := memonew.Lines;
dbgs('sub=');
dbgm(sub); //№1
slovtoNew(i);
dbgs('sub=');
dbgm(sub); //№2
у mem'ов типа Tstrings, для большей совместимости Tstrings
TStrings - абстрактный класс
TStringList = class(TStrings) - потомок TStrings, в котором реализован функционал для работы со строками
несмотря на то, что TMemo.Lines: TStrings,
создаются они всё-равно так Lines := TStringList.Create;
несмотря на то, что TMemo.Lines: TStrings,
создаются они всё-равно так Lines := TStringList.Create;
в stdctrls мы можем видеть что это не так:
оно и логично, они виртуальные
создаются они всё-равно так Lines := TStringList.Create;
Готов поспорить что в сэттере свойства Lines происходит копирование содержимого свежесозданного TStringList-а во внутреннюю коллекцию строк (FLines). ;)
[QUOTE=hardcase]Готов поспорить что в сэттере свойства Lines происходит копирование содержимого свежесозданного TStringList-а во внутреннюю коллекцию строк (FLines)[/QUOTE]
суть не в том, чтобы дать выкладки из исходников borland, а показать, что декларировать переменную мы можем как абстрактный класс (и работать с ней в соответствии с этим классом - свойства, методы), а создавать ее, как наследника этого класса (абстрактного)
S1, S2: TStrings;
begin
S1 := TStringListCreate;
S2 := TMemoStrings.Create;
при этом мы можем использовать один и тот-же код для обработки переменных разных классов (главное, чтобы они были наследниками одного класса, свойства и методы которого мы используем)
MyInt: Integer;
//сохранение свойств в поток
procedure SaveToStream(Stream: TStream);
begin
Stream.Write(MyInt, SizeOf(MyInt));
end;
//сохранение свойств в файл
procedure SaveToFile(FileName: TFileName);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
SaveToStream(Stream);
finally
Stream.Free;
end;
end;
если меняется количество или тип свойств - меняем первую процедуру, и обе валидно работают
ну а как еще ответить на утверждение
создаются они всё-равно так Lines := TStringList.Create;
?
или я чего-то не понял :)
при этом мы можем использовать один и тот-же код для обработки переменных разных классов
...
если меняется количество или тип свойств - меняем первую процедуру
так оно и понятно, полиморфизм in action
спасибо сем за внимание =