使用泛型的枚举 [英] Using an enum with generics

查看:1150
本文介绍了使用泛型的枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个通用类,我可以使用一组枚举来启动其中的值。例如:

I'm trying to create a generic class to which I can use a set of enums to initiate the values inside. For example:

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;

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

Additionally, later methods will fetch objects, via the enum value, for example:

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

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

However, passing as a generic parameter, delphi doesn't know that TEnum is going to be an enum. Can I enforce that in some way?

推荐答案

正如David所提到的那样,您可以做的最好的是在运行时使用RTTI。

As David mentioned the best you can do is at runtime with 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;  

虽然我不知道代码行为如何,当你的枚举已经定义了值,例如

Although I don't know how the code behaves when your enum has defined values such as

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






编辑:


如果你想返回 iterValue 到枚举,您可以使用以下功能,从 enf helper class by Jim Ferguson

If you would like to return iterValue to the enum, you may use the following function, taken from a 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;

然后,您可以使用一般提供的构造函数中的字典索引。

You may then use the generically provided as the index to the dictionary in your constructor.

这篇关于使用泛型的枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆