我可以创建一个反序列化我的对象的字符串版本的构造函数吗?

Lar*_*tig 5 delphi serialization delphi-2010

我正在使用Delphi帮助文件中的ComponentToString部分中的示例对对象(TComponent后代)进行序列化和反序列化.这样我就可以将对象存储在数据库的VARCHAR字段中.

当我需要从存储在数据库中的字符串实例化我的类的新实例时,我可以使用表单的构造函数来实现CreateFromString(AOwner: TComponent; AData: String)吗?或者我是否必须使用返回组件类实例的非类方法?

如果我可以使用构造函数版本,如何将ReadComponent的返回值"映射"到构造函数创建的"self"?

这是帮助文件中的反序列化示例:

function StringToComponentProc(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result:= BinStream.ReadComponent(nil);
    finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Rob*_*edy 6

通常,是的,您可以使构造函数反序列化字符串并使用该信息初始化新实例.一个简单的例子是具有单个Integer字段的类.将字符串传递给构造函数并让构造函数调用StrToInt并使用结果初始化该字段.

但是如果反序列化的唯一函数是也创建实例的函数,那么你就不能在构造函数中使用它,因为当你只需要一个实例时,你最终会得到两个实例.构造函数没有办法说,"没关系;毕竟不要构造一个实例.我已经在其他地方找到了一个."

但是,这不是您所处的情况.您应该知道,TStream.ReadComponent允许您自己创建实例.如果您尚未为其提供要使用的实例,则它仅实例化该类.您应该能够像这样编写构造函数:

constructor TLarryComponent.CreateFromString(const AData: string);
var
  StrStream, BinStream: TStream;
begin
  Create(nil);
  StrStream := TStringStream.Create(AData);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Position := 0;
      BinStream.ReadComponent(Self);
    finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

在那里,我们将当前对象传递SelfReadComponent.流将忽略存储在流中的类名,并假设当前对象具有正确的类.

  • 您的实施中是否可能存在小错误?我认为它应该是`Create(nil)`; 不是`继承了Create(nil);`.使用"继承",您将错过创建TLarryComponent引入的任何字段存储和属性. (2认同)