delphi – 需要将唯一的整数值与类相关联

前端之家收集整理的这篇文章主要介绍了delphi – 需要将唯一的整数值与类相关联前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
好吧,所以我有一个基类,我们称之为TFruit.从这里有各种后代,如TApple,TOrange等.我需要将后代类的属性保存到文件中.

为了能够在加载数据时创建正确的类,每个类都需要具有在写入实际数据之前写入文件的ID.目前,我已经提出了以下方法

type
  TFruit = class
    const ID = 0;
  end;

  TApple = class(TFruit)
    const ID = 1;
  end;

  TOrange = class(TFruit)
    const ID = 2;
  end;

测试这个,我发现我需要非常小心我宣布哪个类.如果我用这个:

var Fruit: TFruit;

  Fruit := TOrange.Create;

…然后Fruit.ID将返回零.但是,将Fruit声明为TOrange将产生预期的结果Fruit.ID = 2(任何人都知道为什么?)

所以基本上,我这样做是对还是有更好的方法呢?通过比较(额外的函数声明,实现和代码),必须创建一个类函数并从那里返回一个值似乎非常难看.

解决方法

更容易维护的解决方案是创建一个映射类,您可以在其中注册要转换为整数的所有类.

好处

>能够检测重复的注册.
>独立于您的班级结构.
>包括转换回类名.

用法

RegisterClass.Register(0,TFruit);
  RegisterClass.Register(1,TApple);
  RegisterClass.Register(2,TOrange);

履行

TRegisterClass = class
  private
    FList: TStringList;
  public
    function FindID(AClass: TClass): Integer;
    function FindClassName(const ID: Integer): string;
    procedure Register(const ID: Integer; AClass: TClass);
  end;
  ...
  function TRegisterClass.FindID(AClass: TClass): Integer;
  begin
    Assert(Assigned(AClass));

    Result := -1;
    if FList.IndexOf(AClass.ClassName) <> -1 then
      Result := Integer(FList.Objects[FList.IndexOf(AClass.ClassName)]);
  end;

  function TRegisterClass.FindClassName(const ID: Integer): string;
  var
    I: Integer;
  begin
    Result := EmptyStr;
    for I := 0 to Pred(FList.Count) do
      if Integer(FList.Objects[I]) = ID then
      begin
        Result := FList[I];
        Exit;
      end;
  end;

  procedure TRegisterClass.Register(const ID: Integer; AClass: TClass);
  begin
    if IsAlreadyRegistered(ID) then 
      raise Exception.Create('Duplicate ID Registration')
    else if IsAlreadyRegistered(AClass) then 
      raise Exception.Create('Duplicate Class Registration');

    FList.AddObject(AClass.ClassName,Pointer(ID)); 
  end;

请注意,有一个更好的结构可以将String映射到整数.在没有编译器的情况下编写这个并且不了解Delphi5之外的许多基本结构,我选择了一个明显的实现.

请注意,仍然必须编写IsAlreadyRegistered重载函数

猜你在找的Delphi相关文章