1

我有一个带有属性列表的基本类。然后创建子类并添加另一个属性。我需要将组件存储到文件中。但是不是存储子组件,而是写入父组件。

下面是一个演示该问题的示例。

  MyComp1 = class(TComponent)
  strict private
    FS: string;
    FI: Integer;
  published
    property S: string read FS write FS;
    property I: Integer read FI write FI;
  end;

  MyComp2 = class(MyComp1)
  strict private
    FS2: string;
  published
    property S2: string read FS2 write FS2;
  end;

procedure SaveIt;
var
  MS: TMemoryStream;
  C1: MyComp1;
  C2: MyComp2;
begin
  MS := TMemoryStream.Create;
  try
    C1 := MyComp1.Create(nil);
    C1.S := 'Hallo, World!';
    C1.I := 100500;
    C2 := MyComp2(C1);
    C2.S2 := 'Second string';
    MS.WriteComponent(C2);
    MS.Position := 0;
    MS.SaveToFile('C:\test.dat');
  finally
    MS.Free;
  end;
end;

细节:

我有随时间扩展的功能。所以我创建了 TComponent 的基类(我们称之为 MyComp1)和这种类型的变量(MyComp: MyComp1)。一旦我扩展功能,我从以前的版本创建后代类 (MyComp2 = class(MyComp1)) 添加新的需要的属性并像这样分配它的值

MyComp2(MyComp).S2 := 'Second string';

然后我需要将 MyComp 组件保存到文件中,但带有子属性。我确实像这样创建它

MyComp := MyComp2.Create(nil)

但将其保存到文件中只有 MyComp1 的属性

4

1 回答 1

1

它不起作用,因为您正在实例化 的对象,MyComp1然后将其类型转换为MyComp2. 它不是MyComp2内存中的实际对象,因此将值写入对象的MyComp2属性MyComp1是访问不属于 MyComp1 对象的内存的无效操作,因此它充其量会崩溃,更糟的是会损坏内存。

处理这种情况的正确方法是自己创建一个对象实例MyComp2,根本不创建MyComp1MyComp2从 继承成员MyComp1,因此您可以访问对象MyComp1的属性MyComp2,例如:

procedure SaveIt;
var
  MS: TMemoryStream;
  Comp: MyComp2;
begin
  MS := TMemoryStream.Create;
  try
    Comp := MyComp2.Create(nil);
    try
      Comp.S := 'Hallo, World!';
      Comp.I := 100500;
      Comp.S2 := 'Second string';
      MS.WriteComponent(Comp);
    finally
      Comp.Free;
    end;
    MS.Position := 0;
    MS.SaveToFile('C:\test.dat');
  finally
    MS.Free;
  end;
end;
于 2012-12-16T01:18:07.883 回答