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

标签 delphi generics rtti

我正在尝试编写一个规范实用程序库。

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

TExpression 之一是 TPropertyExpression。它只是一个表达式,通过 Rtti 的名称获取属性的值。

我用最简单的方式实现了它,但真的不明白为什么它会向我抛出反病毒。

我用调试器一步一步地进行。所有类型都是它们应该的类型。我只是不知道为什么 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.

最佳答案

GetValue 需要实例指针 (aObject),但您要向其传递指针变量的地址 (@aObject)。

将您的 TObjectType 限制为类类型:

type
  TPropertyExpression<TObjectType: class; TResultType> = class...

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

  aValue := aProperty.GetValue(Pointer(aObject));

关于Delphi Rtti Get Property - 为什么这会导致 AV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36806183/

相关文章:

.net - Delphi 7 中的 Soap 信封 header 不包括 utf-8 编码。我该如何修改它?

delphi - 使用 poPropagateChanges 和 poFetchDetailsOnDemand 避免 ClientDataSets 中的内存损坏?

C# 通用运算符 - RTTI 方法

Delphi: ListView 中的 Shift-Up 和 Shift-Down

delphi - Delphi 'environment variables' 例如 $(BDS) 如何评估?

c# - 如何在迭代时从通用列表中删除元素?

java - 无法在 Java 中调用通用对象的方法

generics - 实现多个特征的通用类型

c++ - 什么时候在没有 RTTI 的情况下编译 c++ 会导致问题?

德尔福RTTI : Get property's class