使用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;
var
Methods: TStringList;
begin
Methods := GetClassElementNames(TSomeClass);
try
...
finally
Methods.Free;
end;
end;
如果您想传递一个对象实例而不是类类型,您可以像这样包装GetClassElementNames()
:
function GetObjectElementNames(Object: TObject): TStringList;
begin
Result := GetClassElementNames(Object.ClassType);
end;
话虽如此,但是返回一个新的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;
var
Methods: TStringList;
begin
Methods := TStringList.Create;
try
GetClassElementNames(TSomeClass, Methods);
...
finally
Methods.Free;
end;
end;
TRttiType.GetDeclaredMethods()
代替TRttiType.GetMethods()
。这将仅返回在指定类中显式声明的方法,并忽略任何未在该类中被覆盖的继承方法。如果想要忽略构造函数和析构函数,可以在调用TStringList.Add()
之前检查TRttiMethod.IsConstructor
和TRttiMethod.IsDestructor
。 - Remy Lebeau