You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi的TMyClass中实现带字符串参数的默认索引属性

实现Delphi类的索引器简化属性访问

原问题背景

现有类定义(修正笔误后):

type TMyItem = class(TObject)
private
  FReference: String;
  FOtherProperty: TObject; // 修正原代码中属性与字段类型不一致的问题
public
  property Reference: String read FReference write FReference;
  // 修正原代码属性声明的语法错误
  property OtherProperty: TObject read FOtherProperty write FOtherProperty;
end;

type TMyListClass = class(TObjectList<TMyItem>)
public
  function IndexOf(const AReference: String): Integer; overload;
end;

function TMyListClass.IndexOf(const AReference: String): Integer;
var
  I: Integer;
begin
  Result := -1;
  for I := 0 to Count - 1 do
    if Items[I].Reference = AReference then
    begin
      Result := I;
      Break;
    end;
end;

// 修正原代码FList类型笔误,改为TMyListClass以使用自定义IndexOf方法
type TMyClass = class(TObject)
private
  FList: TMyListClass;
public
  property List: TMyListClass read FList write FList;
end;

当前需要通过冗长的代码访问属性:

AMyClass.List.Items[AMyClass.List.IndexOf(ARef)].OtherProperty := AOtherObject;

希望简化为:

AMyClass[ARef].OtherProperty := AOtherObject;

解决方案:给TMyClass添加带参数的默认属性

通过给TMyClass定义带字符串参数的默认属性,内部封装索引查找逻辑,即可实现目标简化写法。

1. 修改TMyClass的定义

添加默认属性Items,并声明对应的读写方法:

type TMyClass = class(TObject)
private
  FList: TMyListClass;
  function GetItem(const AReference: String): TMyItem;
  procedure SetItem(const AReference: String; Value: TMyItem);
public
  constructor Create; virtual;
  destructor Destroy; override;
  property List: TMyListClass read FList write FList;
  // 标记为默认属性,接受字符串类型的Reference参数
  property Items[const AReference: String]: TMyItem read GetItem write SetItem; default;
end;

2. 实现读写方法与构造/析构函数

constructor TMyClass.Create;
begin
  inherited;
  // 传入True表示自动释放列表内的TMyItem对象,可按需调整
  FList := TMyListClass.Create(True);
end;

destructor TMyClass.Destroy;
begin
  FList.Free;
  inherited;
end;

function TMyClass.GetItem(const AReference: String): TMyItem;
var
  Index: Integer;
begin
  Index := FList.IndexOf(AReference);
  if Index <> -1 then
    Result := FList.Items[Index]
  else
    Result := nil; // 可根据需求改为抛出异常,如:raise Exception.Create('Item not found');
end;

procedure TMyClass.SetItem(const AReference: String; Value: TMyItem);
var
  Index: Integer;
begin
  Index := FList.IndexOf(AReference);
  if Index <> -1 then
    FList.Items[Index] := Value
  else
    FList.Add(Value); // 按需改为抛出异常或其他逻辑
end;

使用效果

现在可以直接通过索引器语法访问目标对象:

// 读取属性
var Obj: TObject;
Obj := AMyClass[ARef].OtherProperty;

// 设置属性
AMyClass[ARef].OtherProperty := AOtherObject;

关键说明

  • 默认属性通过default关键字标记,Delphi允许类定义一个默认属性,使用时可省略属性名,直接用类实例[参数]的形式访问。
  • 读写方法内部复用了TMyListClass的IndexOf方法,无需重复编写查找逻辑。
  • 找不到对应Reference的Item时,可根据业务需求选择返回nil、抛出异常或自动添加新Item,示例中采用返回nil和自动添加的逻辑,可自行调整。

内容的提问来源于stack exchange,提问作者SiBrit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:31:03