我可以将Class类型作为过程参数传递吗 [英] Can I pass a Class type as a procedure parameter

查看:487
本文介绍了我可以将Class类型作为过程参数传递吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个将某个类的所有名称作为字符串列表返回的函数。基于先前的解决方案/问题,我尝试对该代码进行失败

I want to create a function that returns all the names of a certain class as a string list. Based on the previous solution / question I tried to this code with no success

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;


推荐答案

使用 TClass ,这是 TRttiContent.GetType()所期望的。

您也没有分配填充前的结果。

You are also not allocating the Result before filling it.

尝试一下:

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()像这样:

If you want to pass in an object instance instead of a class type, you can wrap GetClassElementNames() like this:

function GetObjectElementNames(Object: TObject): TStringList;
begin
  Result := GetClassElementNames(Object.ClassType);
end;

这样说,返回一个新的TStringList对象不是一个好主意。如果调用方分配TStringList并将其传递给函数以进行填写,则更好,更灵活,例如:

With that said, it is not a good idea to return a new TStringList object. It is better, and more flexible, if the caller allocates the TStringList and passes it to the function to fill in, eg:

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;
}

var
  Methods: TStringList;
begin
  Methods := TStringList.Create;
  try
    GetClassElementNames(TSomeClass, Methods);
    ...
  finally
    Methods.Free;
  end;
end;

这篇关于我可以将Class类型作为过程参数传递吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆