1
我想寫一個規範實用程序庫。Delphi Rtti獲取屬性 - 爲什麼這會導致AV?
規範之一是一個TExpressionSpecification。基本上,它通過評估內部TE表達來實現規範模式。
其中一個TExpression是TPropertyExpression。它只是一個表達式,它通過Rtti的名稱獲取屬性的值。
我以最簡單的方式實現了它,但真的無法理解它爲什麼會向我拋出AV。
我帶着調試器走了過去。所有類型都是他們應該是的。我只是不知道爲什麼TRttiProperty.GetValue破壞破壞。
任何人都可以幫忙嗎? 單位規格;
interface
uses
Classes;
type
TPropertyExpression<TObjectType, TResultType> = class
private
FPropertyName: string;
public
constructor Create(aPropertyName: string); reintroduce;
function Evaluate(aObject: TObjectType): TResultType;
property PropertyName: string read FPropertyName write FPropertyName;
end;
procedure TestIt;
implementation
uses
Rtti;
constructor TPropertyExpression<TObjectType, TResultType>.Create(aPropertyName:
string);
begin
inherited Create;
PropertyName := aPropertyName;
end;
function TPropertyExpression<TObjectType, TResultType>.Evaluate(aObject:
TObjectType): TResultType;
var
aCtx : TRttiContext;
aModelType : TRttiType;
aResultType : TRttiType;
aProperty : TRttiProperty;
aValue : TValue;
begin
aCtx := TRttiContext.Create;
aModelType := aCtx.GetType(System.TypeInfo(TObjectType));
aResultType := aCtx.GetType(System.TypeInfo(TResultType));
aProperty := aModelType.GetProperty(PropertyName);
aValue := aProperty.GetValue(Addr(aObject));
Result := aValue.AsType<TResultType>;
end;
procedure TestIt;
var
aComponent : TComponent;
aSpec : TPropertyExpression<TComponent, string>;
begin
aComponent := TComponent.Create(nil);
aComponent.Name := 'ABC';
aSpec := TPropertyExpression<TComponent, string>.Create('Name');
WriteLn(aSpec.Evaluate(aComponent));
Readln;
end;
end.
沒有必要強制類型轉換爲'Pointer',只是通過對象指針原來是:'GetValue(aObject)'。 –
另外,請記住記錄也可以有屬性,所以你不應該使用'class'約束。除非你定義一個獨立的表達式類來獨立於類實例處理記錄實例。 –
沒有演員,我得到E2010不兼容的類型:'指針'和'TObjectType'。雖然你說得對,記錄可以有屬性,但是記錄屬性的RTTI不受支持。所以我只是假設只限制類類型就行了。 –