加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 使用带有泛型的枚举

发布时间:2020-12-15 09:31:34 所属栏目:大数据 来源:网络整理
导读:我正在尝试创建一个泛型类,我可以使用一组枚举来启动内部的值.例如: constructor TManagerTEnum.Create;var enum: TEnum; enumObj: TMyObject;begin fMyObjectList:= TObjectDictionaryTEnum,TMyObject.Create([doOwnsValues],10); for enum:= Low(TEnum) t
我正在尝试创建一个泛型类,我可以使用一组枚举来启动内部的值.例如:

constructor TManager<TEnum>.Create;
var
  enum: TEnum;
  enumObj: TMyObject;
begin
  fMyObjectList:=  TObjectDictionary<TEnum,TMyObject>.Create([doOwnsValues],10);
  for enum:= Low(TEnum) to High(TEnum) do
  begin
    enumObj:= TMyObject.Create();
    fMyObjectList.Add(enum,enumObj);
  end;
end;

此外,以后的方法将通过枚举值获取对象,例如:

function TManager<TEnum>.Fetch(enum: TEnum): TMyObject;
begin
  fMyObjectList.TryGetValue(enum,Result);
end;

但是,作为通用参数传递,delphi不知道TEnum将是一个枚举.我能以某种方式强制执行吗?

解决方法

正如David提到的那样,你可以做的最好的事情就是在运行时使用RTTI.

type  
      TRttiHelp = record
        class procedure EnumIter<TEnum {:enum}>; static;
      end;

    class procedure TRttiHelp.EnumIter<TEnum {:enum}>;
    var
      typeInf: PTypeInfo;
      typeData: PTypeData;
      iterValue: Integer;
    begin
      typeInf := PTypeInfo(TypeInfo(TEnum));
      if typeInf^.Kind <> tkEnumeration then
        raise EInvalidCast.CreateRes(@SInvalidCast);

      typeData := GetTypeData(typeInf);
      for iterValue := typeData.MinValue to typeData.MaxValue do
        WhateverYouWish;
    end;

虽然我不知道当你的枚举定义了诸如的值时代码的行为

(a=9,b=19,c=25)

编辑:

如果您想将iterValue返回到枚举,您可以使用以下函数,取自enum helper class by Jim Ferguson

class function TRttiHelp.EnumValue<TEnum {:enum}>(const aValue: Integer): TEnum;
var
  typeInf: PTypeInfo;
begin
  typeInf := PTypeInfo(TypeInfo(TEnum));
  if typeInf^.Kind <> tkEnumeration then
    raise EInvalidCast.CreateRes(@SInvalidCast);

  case GetTypeData(typeInf)^.OrdType of
    otUByte,otSByte:
      PByte(@Result)^ := aValue;
    otUWord,otSWord:
      PWord(@Result)^ := aValue;
    otULong,otSLong:
      PInteger(@Result)^ := aValue;
  else
    raise EInvalidCast.CreateRes(@SInvalidCast);
  end;
end;

然后,您可以使用通常提供的作为构造函数中字典的索引.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读