Delphi Rtti Get Property - 为什么会导致AV?

Lud*_*c C 1 delphi generics rtti

我正在尝试编写一个spec实用程序库.

规范之一是TExpressionSpecification.基本上,它通过评估内部TExpression来实现规范模式.

其中一个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.
Run Code Online (Sandbox Code Playgroud)

Ond*_*lle 5

GetValue期望实例指针(aObject),但你传递指针变量(@aObject)的地址.

限制你TObjectType的类类型:

type
  TPropertyExpression<TObjectType: class; TResultType> = class...
Run Code Online (Sandbox Code Playgroud)

然后,而不是Addr(aObject)直接传递实例:

  aValue := aProperty.GetValue(Pointer(aObject));
Run Code Online (Sandbox Code Playgroud)