使用Delphi 10我有两个work_start
和work_finish
类型的TTime
private
fWorkStart: TTime;
function GetWS: TTime;
procedure SetWS(const Value: TTime);
Public
property WorkStart: TTime read GetWS write SetWS;
....
procedure MyClass.SetWS(const Value: TTime);
begin
fWorkStart := value;
mydataset.Edit;
mydataset.FieldByName('work_start').AsDateTime := fWorkStart;
mydataset.Post;
end;
function MyClass.GetWS: TTime;
begin
if mydataset.FieldByName('work_start').IsNull then
fWorkStart := encodetime(6,0,0,0)
else
fWorkStart := mydataset.FieldByName('work_start').AsDateTime;
result := fWorkStart;
end;
我需要从数据库表中读取和写入所以我为每个人创建一个属性,就像那样
full
WorkFinish属性是一样的。那么有两种方法可以创建一个属性,或者我的代码很好吗?
答案 0 :(得分:4)
Craig's answer演示了记录属性,这意味着您将一个属性设置为一个单元;您无法独立设置开始和结束时间。 Dawood's answer演示了一个数组属性,它允许独立访问,但在使用者身上施加了繁琐的括号表示法。 Kobik's comment改进了语义,但我们可以使用index specifiers做得更好。
首先,定义一个枚举来表示两种情况:
type
TWorkTime = (wtStart, wtFinish);
在属性声明中使用这些值,并为属性访问器提供一个额外的参数来表示索引:
private
FWorkTime: :array[TWorkTime] of TTime;
function GetWT(Index: TWorkTime): TTime;
procedure SetWT(Index: TWorkTime; const Value: TTime);
public
property WorkStart: TTime index wsStart read GetWT write SetWT;
property WorkFinish: TTime index wsFinish read GetWT write SetWT;
要减少访问者中的the bloat Craig warns about,可以使用相应的字段名称定义另一个数组,这样可以避免为不同的字段重复代码:
const
FieldNames: array[TWorkTime] of string = (
'work_start',
'work_finish'
);
function MyClass.GetWT(Index: TWorkTime): TTime;
begin
if mydataset.FieldByName(FieldName[Index]).IsNull then
FWorkTime[Index] := EncodeTime(6, 0, 0, 0)
else
FWorkTime[Index] := mydataset.FieldByName(FieldNames[Index]).AsDateTime;
Result := FWorkTime[Index];
end;
答案 1 :(得分:1)
有可能:
//Define a record to hold both
type
TTimeRange = record
StartTime: TTime;
EndTime: TTime;
end;
//And have your property use the record
property WorkHours: TTimeRange read GetWorkHours write SetWorkHours;
但是,这会强制您的类的客户端使用记录结构进行交互。基本上你遇到的并发症超过了你获得的小益处。
所以我不推荐它 (虽然它值得记住这项技术,因为在其他情况下它可能会更有用。)
至于你的代码:
fWorkStart
是多余的。Edit
和Post
。除了在Db中一次更新1个字段效率非常低的事实之外,您的方法具有意想不到的副作用。 (你能不能总是假设编辑是正确的选择而不是插入?)答案 2 :(得分:1)
是的,您可以使用索引属性
property WorkTime[IsStart: Boolean]: TDataTime read GetWorkTime write SetWorkTime;
procedure MyClass.SetWorkTime(IsStart: Boolean;const value: TDataTime);
begin
mydataset.Edit;
if IsStart then
mydataset.FieldByName('work_start').AsDateTime := value else
mydataset.FieldByName('work_Finish').AsDateTime := value;
mydataset.Post;
end;
function MyClass.GetWorkTime(IsStart: Boolean): TTime;
begin
if IsStart then
Begin
if mydataset.FieldByName('work_start').IsNull then
fWorkStart := encodetime(6,0,0,0)
else
fWorkStart := mydataset.FieldByName('work_start').AsDateTime;
result := fWorkStart;
end else
begin
if mydataset.FieldByName('work_finish').IsNull then
fWorkfinish := encodetime(6,0,0,0)
else
fWorkfinish := mydataset.FieldByName('work_finish').AsDateTime;
result := fWorkfinish;
end
end;