我可以将Class类型作为过程参数传递

Fra*_*anz 4 delphi parameter-passing

我想创建一个函数,将某个类的所有名称作为字符串列表返回.基于之前的解决方案/问题,我尝试使用此代码但没有成功

function  GetClassElementNames (TObject ) : TStringlist ;
var
  LCtx : TRttiContext;
  LMethod : TRttiMethod;
begin
  try
    LCtx:=TRttiContext.Create;
    try
      // list the methods for the any class  class
      for LMethod in  LCtx.GetType(TObject).GetMethods do
        result.add(LMethod.Name);
    finally
      LCtx.Free;
    end;
  except
    on E: Exception do
      result.add (E.ClassName + ': ' +  E.Message);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 12

使用TClass的是,其中TRttiContent.GetType()预计反正.

在填写结果之前,您也没有分配结果.

试试这个:

function GetClassElementNames(Cls: TClass) : TStringlist ;
var
  LCtx : TRttiContext;
  LMethod : TRttiMethod;
begin
  Result := TStringList.Create;
  try
    LCtx := TRttiContext.Create;
    try
      for LMethod in LCtx.GetType(Cls).GetMethods do
        Result.Add(LMethod.Name);
    finally
      LCtx.Free;
    end;
  except
    on E: Exception do
      Result.Add(E.ClassName + ': ' +  E.Message);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

var
  Methods: TStringList;
begin
  Methods := GetClassElementNames(TSomeClass);
  try
    ...
  finally
    Methods.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如果要传入对象实例而不是类类型,可以GetClassElementNames()像这样包装:

function GetObjectElementNames(Object: TObject): TStringList;
begin
  Result := GetClassElementNames(Object.ClassType);
end;
Run Code Online (Sandbox Code Playgroud)

话虽如此,返回一个新的TStringList对象并不是一个好主意.如果调用者分配TStringList并将其传递给要填充的函数,则更好,更灵活,例如:

procedure GetClassElementNames(Cls: TClass; AMethods: TStrings);
var
  LCtx : TRttiContext;
  LMethod : TRttiMethod;
begin
  try
    LCtx := TRttiContext.Create;
    try
      for LMethod in LCtx.GetType(Cls).GetMethods do
        AMethods.Add(LMethod.Name);
    finally
      LCtx.Free;
    end;
  except
    on E: Exception do
      AMethods.Add(E.ClassName + ': ' +  E.Message);
  end;
end;

{
procedure GetObjectElementNames(Object: TObject; AMethods: TStrings);
begin
  GetClassElementNames(Object.ClassType, AMethods);
end;
}
Run Code Online (Sandbox Code Playgroud)

var
  Methods: TStringList;
begin
  Methods := TStringList.Create;
  try
    GetClassElementNames(TSomeClass, Methods);
    ...
  finally
    Methods.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 使用`TRttiType.GetDeclaredMethods()`而不是`TRttiType.GetMethods()`.这将仅返回在指定类中显式声明的方法,并忽略未在类中重写的任何继承方法.如果要忽略构造函数和析构函数,可以在调用`TStringList.Add()之前检查`TRttiMethod.IsConstructor`和`TRttiMethod.IsDestructor`. (4认同)