2013-09-28 2 views
4

특정 클래스의 모든 이름을 문자열 목록으로 반환하는 함수를 만들고 싶습니다. 내가 TRttiContent.GetType() 예상하는 어쨌든에 성공하지클래스 매개 변수를 프로 시저 매개 변수로 전달할 수 있습니까?

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; 

답변

12

사용 TClass,이 코드에 시도 이전 솔루션/질문 기준으로합니다.

결과를 채우기 전에 결과를 할당하지 않습니다.

이 시도 :

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 객체를 반환하는 것은 좋지 않습니다.

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; 
+0

내가 모든 기본 기능 무료 만들기 좋아 exlude 수 : 호출자가 예를 들어, TStringList를 할당하고 기입하는 함수에 통과하면 그것은 더 나은, 더 유연 의 InitInstance CleanupInstance 하는 ClassType 클래스 이름 ClassNameIs ClassParent ClassInfo InstanceSize Inhe ritsFrom MethodAddress MethodAddress methodName로 QualifiedClassName FieldAddress FieldAddress GetInterface GetInterfaceEntry UnitScope GetHashCode ToString 같음 SafeCallException AfterConstruction을 BeforeDestruction 디스패치 의 DefaultHandler newInstance와 FreeInstance UnitName GetInterfaceTable 신지 로얄 난 내 정의 된 절차에만 사용 – Franz

+0

내가 사용했던 정의가 필요했다 TTest = class .... end; – Franz

+4

'TRttiType.GetMethods()'대신'TRttiType.GetDeclaredMethods()'를 사용하십시오. 그러면 지정된 클래스에서 명시 적으로 선언 된 메서드 만 반환되고 클래스에서 재정의되지 않은 상속 된 메서드는 무시됩니다. 생성자와 소멸자를 무시하고 싶다면'TStringList.Add()'를 호출하기 전에'TRttiMethod.IsConstructor'와'TRttiMethod.IsDestructor'를 체크 할 수 있습니다. –

관련 문제