• Class-reference types 类引用类型--快要失传的技术


    先摘一段原版的说明:

    A class-reference type, sometimes called a metaclass, is denoted by a construction of the form

    class of type  

    where type is any class type. The identifier type itself denotes a value whose type is class of type. If type1 is an ancestor of type2, then class of type2 is assignment-compatible with class of type1. Thus

    type TClass = class of TObject;
    var AnyObj: TClass;

    declares a variable called AnyObj that can hold a reference to any class. (The definition of a class-reference type cannot occur directly in a variable declaration or parameter list.) You can assign the value nil to a variable of any class-reference type.

    To see how class-reference types are used, look at the declaration of the constructor for TCollection (in the Classes unit):

    type TCollectionItemClass = class of TCollectionItem;
      ...
    constructor Create(ItemClass: TCollectionItemClass);

    This declaration says that to create a TCollection instance object, you must pass to the constructor the name of a class descending from TCollectionItem.

    Class-reference types are useful when you want to invoke a class method or virtual constructor on a class or object whose actual type is unknown at compile time.

    当你想要在编译时调用一个类或对象的未知具体(真实)类型中的一个类方法或构造器函数时,类引用类型是很有用的。

    光看帮助你大概搞不清楚这个有什么用。我举一个例子,一般mainform都有很多菜单按钮,用来打开不同的窗口,通常做法要在uses部分添加所有要引用的单元,十分麻烦,用上面的技术就可以避免引用。假设所有的业务窗口都从TAppBasicForm继承,你可以声明这样的类型:

    TTAppBasicFormClass = class of TTAppBasicForm;

    然后在每个业务窗口代码结尾处加上:

    initialization
      RegisterClass(TBusMemberNewForm); //TBusMemberNewForm从TAppBasicForm继承

    finalization
      UnRegisterClass(TBusMemberNewForm);

    最后在Mainform用下面的函数:

    procedure TTMainForm.ShowForm(sFormClass: string);
    var
      AppFormClass: TTAppBasicFormClass;
    begin
      try
        AppFormClass := TTAppBasicFormClass(FindClass(sFormClass));
        with AppFormClass.Create(self) do begin
          Show;
        end;
      except
        ShowMessage('Class ‘+sFormClass+' not exist or not register!');
      end;
    end;

    这个函数的参数就是要打开的窗口类名

    更进一步,因为项目中Menu的hint属性不会用到,可以用来存储要打开的类名,如下:

    procedure TTMainForm.MainFormMenuClick(Sender: TObject);
    var
      sFormName: string;
    begin
      with sender as TMenuItem do begin
        sFormName := Trim(Hint);
        if sFormName<>'' then ShowForm(sFormName);
      end;
    end;

    procedure TTMainFaceForm.SetMenuAction;
    var
      i: integer;
    begin
      for i:=0 to ComponentCount-1 do begin
        if Components[i] is TMenuItem then begin
          with Components[i] as TMenuItem do
            if Trim(Hint)<>'' then OnClick := MainFormMenuClick;
        end;
      end;
    end;

    这样的话每增加一个菜单,只要指定菜单的hint属性就自动实现打开对应业务的功能,避免引用单元,也不用写菜单的onclick代码,非常简洁。当然这个还用到了RegisterClass和FindClass的技术,去看帮助就明白了。

  • 相关阅读:
    [离散数学]集合3.1、3.2、3.3
    Hadoop YARN ResourceManager 未授权访问漏洞复现
    dns域传送漏洞
    文件包含漏洞详解
    XXE漏洞详解
    常见cms
    IP地址详解
    帧详解
    IP包头内容详解
    SSRF漏洞详解
  • 原文地址:https://www.cnblogs.com/yzryc/p/6394650.html
Copyright © 2020-2023  润新知