【问题标题】:Do Delphi Attributes require a constant parameter? If so, why?Delphi 属性是否需要常量参数?如果是这样,为什么?
【发布时间】:2011-08-22 15:00:48
【问题描述】:

考虑以下(不可编译的)代码:

program AttributesTestProgram;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  Classes,
  RTTI;

type

  TDisplayTextAttribute = class(TCustomAttribute)
  private
    FDisplayText: string;
  public
    constructor Create(aDisplayText: string);
    property DisplayText: string read FDisplayText write FDisplayText;
  end;

constructor TDisplayTextAttribute.Create(aDisplayText: string);
begin
  FDisplayText := aDisplayText;
end;

function GetFirstName: string;
begin
  Result := 'First Name';
end;


type
  TCustomer = Class(TObject)
  private
    FFirstName: string;
    FLastName: string;
    FStreetAddress: string;
    FZIP: string;
    FState: string;
    FCity: string;
    FPhone: string;
  published
    [TDisplayTextAttribute(GetFirstName)]
    property FirstName: string read FFirstName write FFirstName;
  end;

begin
  // Code that does the work removed for clarity....
  Readln;
end.

我自然想知道为什么编译失败并出现错误:

[DCC Error] AttributesTestProgram.dpr(40): E2026 Constant expression expected

我认为这与属性必须在编译器时绑定的想法有关,或者类似的东西。

因此,我的问题是:

有什么方法可以在这里“击败系统”并在属性中的那个位置获取运行时值?

【问题讨论】:

    标签: delphi function constants


    【解决方案1】:

    是的,您需要常量,因为参数在编译时被评估为常量并存储在 RTTI 表中。此外,属性属于类,而不属于对象实例,所以如果你有多个 TCustomer,你的想法就变得毫无意义。

    您可以通过为属性提供无参数构造函数(或根本没有构造函数)并将 DisplayText 属性更改为接受字符串或可以从中提取字符串的对象的方法来击败系统。

    【讨论】:

    • 谢谢,梅森。我会玩弄它。
    • 我如何在属性声明中调用这个新方法?
    • @Nick: ...就像在任何其他对象上调用方法一样? (不确定我是否理解您的问题。)
    • 接下来,正确的答案是“你无法击败系统,而且你不应该想要”——这正是 Mason 所说的。通过将匿名方法传递给 Delphi Spring 中的 DelegateTo 方法,我找到了另一种使用依赖注入初始化构造函数参数的正确方法——无需尝试调整 [Injection()] 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    相关资源
    最近更新 更多