我需要这方面的帮助:
我将对象属性存储在 DataPacket 类中。 属性定义如下
type
TProperty = class
private
FName: string;
public
constructor Create(const AName: string);
property Name: string read FName;
end;
TIntegerProperty = class(TProperty)
private
FValue: Integer;
protected
procedure SetValue(const AValue:integer);
public
property Value: Integer read FValue write SetValue;
end;
DataPacket 类:
type
TDataPacket = class
private
FProperties: TStringList;
public
function GetIntegerValue(const APropertyName: string): integer;
.....
procedure SetIntegerValue(const APropertyName: string; AValue: integer);
end;
它们的实现方式如下:
function TDataPacket.GetIntegerValue(const APropertyName: string): integer;
var
Pos: integer;
begin
Pos := FProperties.IndexOf(APropertyName);
if Pos > -1 then
Result := TIntegerProperty(FProperties.Objects[Pos]).Value
else
Result := 0;
end;
procedure TDataPacket.SetIntegerValue(const APropertyName: string; AValue: integer);
var
Pos: integer;
AProperty: TIntegerProperty;
begin
Pos := FProperties.IndexOf(APropertyName);
if Pos >- 1 then
TIntegerProperty(FProperties.Objects[Pos]).Value := AValue
else
begin
AProperty:= TIntegerProperty.Create(APropertyName);
AProperty.Value := AValue;
FProperties.AddObject(APropertyName, AProperty);
end;
end;
现在的问题是:我需要定义一个 Status 属性,定义为 TObjectStatus,其中:
type
TStatus = (Deleted, Unchanged, Added , Modified, ChildsModified);
TObjectStatus = Set of TStatus;
关于如何定义、存储和检索它有什么想法吗?
抱歉这么长的解释,并提前感谢您的帮助
迈克尔
最佳答案
第一:
Result := TIntegerProperty(FProperties.Objects[Pos]).Value
有风险,因为如果它不是 TIntegerProperty,你就会崩溃。 使用类似的东西:
Pos := FProperties.IndexOf(APropertyName);
if (Pos >= 0) and (FProperties.Objects[Pos] is TIntegerProperty) then
Result := TIntegerProperty(FProperties.Objects[Pos]).Value
else
Result := 0;
接下来是状态,我认为您不需要它们:
查看列表 - 删除了一个 child :已删除 - 添加了一个 child :添加了 - 子项已更改:ChildsModified
您不需要保持不变,因为在这种情况下,集合是空的。并且您不需要 Modified,因为在这种情况下该集合不为空。
对于属性,您只需添加更改值即可。 如果子项发生更改,您可以直接添加 ChildsModified。或者您可以使用惰性评估并步行所有子项来检查更改。
好的,你可以这样做:
type
TStatus = (stDeleted, stAdded , stModified, stChildsModified);
TObjectStatus = Set of TStatus;
TDataPacket = class;
TProperty = class
private
FName : string;
FParent : TDataPacket;
protected
procedure NotifyChange(const AStatus: TStatus);
public
constructor Create(const AParent: TDataPacket; const AName: string);
property Name: string read FName;
end;
TIntegerProperty = class(TProperty)
private
FValue: Integer;
procedure SetValue(const AValue:integer);
public
property Value: Integer read FValue write SetValue;
end;
TDataPacket = class
private
FProperties: TStringList;
FStatus : TObjectStatus;
protected
procedure NotifyChange(const AStatus: TStatus);
function GetProperty(const AName: string): TProperty;
public
function GetIntegerValue(const APropertyName: string): integer;
procedure SetIntegerValue(const APropertyName: string; AValue: integer);
end;
procedure TProperty.NotifyChange(const AStatus: TStatus);
begin
FParent.NotifyChange(AStatus);
end;
constructor TProperty.Create(const AParent: TDataPacket; const AName: string);
begin
Assert(AParent<>nil);
FName := AName;
FParent := AParent;
end;
procedure TIntegerProperty.SetValue(const AValue:integer);
begin
if AValue<>FValue then begin
FValue := AValue;
NotifyChange(stChildsModified);
end;
end;
procedure TDataPacket.NotifyChange(const AStatus: TStatus);
begin
if AProp=nil then begin
case AStatus of
TStatus = (stDeleted, stAdded , stModified, stChildsModified);
FStatus := FStatus + [AStatus];
end;
function TDataPacket.GetProperty(const AName: string): TProperty;
var
i : Integer;
begin
i := FProperties.IndexOf(AName);
if i>=0 then
Result := TProperty(FProperties.Objects[i])
else
Result := nil;
end;
function TDataPacket.GetIntegerValue(const APropertyName: string): integer;
var
prop : TProperty;
begin
prop := GetProperty(APropertyName);
if (prop<>nil) and (prop is TIntegerProperty) then
Result := TIntegerProperty(prop).Value
else
Result := 0;
end;
procedure TDataPacket.SetIntegerValue(const APropertyName: string; AValue: integer);
var
prop : TProperty;
intprop : TIntegerProperty;
begin
prop := GetProperty(APropertyName);
if (prop<>nil) and not (AProperty is TIntegerProperty) then begin
// PANIC!
end else begin
if prop=nil then begin
intprop := TIntegerProperty.Create(self, APropertyName);
intprop.Value := AValue;
FProperties.AddObject(APropertyName, intprop);
NotifyChange(stAdded);
end else begin
TIntegerProperty(prop).Value := AValue;
end;
end;
end;
当然还要添加对删除的支持。
您可以让属性处理所有更改(构造时添加,释放时删除)。
关于delphi - 对象状态(子集)持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/667897/