如何使用通用枚举类型调用 Get Enum Name?

2023-11-23

我有一个使用枚举泛型类型的泛型类。我的问题如何在该类型的实例上使用 GetEnumName?

我创建了一个小型演示类来说明问题:

type
  TEnumSettings<TKey: record > = class
    private
      Key: TKey;
    public
      constructor Create(aKey: TKey);
      function ToString: string; override;
    end;

uses
  TypInfo;


{ TEnumSettings<TKey> }

constructor TEnumSettings<TKey>.Create(aKey: TKey);
begin
  if PTypeInfo(System.TypeInfo(TKey)).Kind <> tkEnumeration then
    Exception.Create(string(PTypeInfo(System.TypeInfo(TKey)).Name) + ' is not an Enumeration');
  Key := aKey;
end;

function TEnumSettings<TKey>.ToString: string;
begin
  Result := GetEnumName(System.TypeInfo(TKey), Integer(Key)) <== HERE I get a compile error: Invalid type cast
end;

我正在使用德尔福XE。那么这可以做到吗?如果是的话怎么办?


就我个人而言,我会通过致电来做到这一点Move。我有以下类型:

type
  TEnumeration<T: record> = class
  strict private
    class function TypeInfo: PTypeInfo; inline; static;
    class function TypeData: PTypeData; inline; static;
  public
    class function IsEnumeration: Boolean; static;
    class function ToOrdinal(Enum: T): Integer; inline; static;
    class function FromOrdinal(Value: Integer): T; inline; static;
    class function MinValue: Integer; inline; static;
    class function MaxValue: Integer; inline; static;
    class function InRange(Value: Integer): Boolean; inline; static;
    class function EnsureRange(Value: Integer): Integer; inline; static;
  end;

{ TEnumeration<T> }

class function TEnumeration<T>.TypeInfo: PTypeInfo;
begin
  Result := System.TypeInfo(T);
end;

class function TEnumeration<T>.TypeData: PTypeData;
begin
  Result := TypInfo.GetTypeData(TypeInfo);
end;

class function TEnumeration<T>.IsEnumeration: Boolean;
begin
  Result := TypeInfo.Kind=tkEnumeration;
end;

class function TEnumeration<T>.ToOrdinal(Enum: T): Integer;
begin
  Assert(IsEnumeration);
  Assert(SizeOf(Enum)<=SizeOf(Result));
  Result := 0; // needed when SizeOf(Enum) < SizeOf(Result)
  Move(Enum, Result, SizeOf(Enum));
  Assert(InRange(Result));
end;

class function TEnumeration<T>.FromOrdinal(Value: Integer): T;
begin
  Assert(IsEnumeration);
  Assert(InRange(Value));
  Assert(SizeOf(Result)<=SizeOf(Value));
  Move(Value, Result, SizeOf(Result));
end;

class function TEnumeration<T>.MinValue: Integer;
begin
  Assert(IsEnumeration);
  Result := TypeData.MinValue;
end;

class function TEnumeration<T>.MaxValue: Integer;
begin
  Assert(IsEnumeration);
  Result := TypeData.MaxValue;
end;

class function TEnumeration<T>.InRange(Value: Integer): Boolean;
var
  ptd: PTypeData;
begin
  Assert(IsEnumeration);
  ptd := TypeData;
  Result := Math.InRange(Value, ptd.MinValue, ptd.MaxValue);
end;

class function TEnumeration<T>.EnsureRange(Value: Integer): Integer;
var
  ptd: PTypeData;
begin
  Assert(IsEnumeration);
  ptd := TypeData;
  Result := Math.EnsureRange(Value, ptd.MinValue, ptd.MaxValue);
end;

The ToOrdinal方法可以满足您的需要,并且我相信您将能够使其适应您的课程。

如果你不喜欢使用Move这样,你就可以使用TValue.

TValue.From<TKey>(Key).AsOrdinal

@TLama 指出你可以避免打电话GetEnumName完全通过使用

TValue.From<TKey>(Key).ToString

从表面上看,使用TValue似乎更符合泛型和 RTTI 的精神。致电Move依赖于枚举类型的具体实现细节。然而,单步执行调试器并观察执行过程中涉及多少代码是非常有趣的TValue.From<TKey>(Key).AsOrdinal。仅此一点就足以让我犹豫是否推荐使用TValue.

实现此目的的另一种方法是使用TRttiEnumerationType:

TRttiEnumerationType.GetName<TKey>(Key)

这样做的实现比使用要高效得多TValue.ToString,只不过是一个电话GetEnumName.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用通用枚举类型调用 Get Enum Name? 的相关文章

  • 查找字符串是否在列表中的最佳方法(没有泛型)

    我想做这样的事情 Result MyString in string1 string2 string3 string4 这不能与字符串一起使用 我不想做这样的事情 Result MyString string1 or MyString st
  • Delphi - 获取和设置 ListView 的滚动条位置

    这似乎是一个愚蠢而简单的问题 然而 我一直无法找到令人满意的答案 基本上 我有一个列表视图 样式 vsReport 与数据 有时 我必须更新它 因此 我必须清除列表视图并用更新的数据再次填充它 但是 当我这样做时 滚动条位置将重置为 0 我
  • C# 抽象泛型方法

    C net 3 5 我正在尝试创建一个具有通用方法的基类 从它继承的类应该指定方法的类型 这样做的前提是创建管理过滤的类 所以我有 public abstract class FilterBase NEED Help Declaring t
  • 可以在滚动条上绘画吗?

    是否可以在 TMemo TListbox 等标准控件的滚动条上进行绘制 我所需要的只是在滚动条上绘制一些基本形状 并且我试图避免从 stratch 实现整个滚动内容 有什么指点吗 蒂亚 确实有可能 你可能想看一下WM NCPAINT消息 这
  • 集合类型名称中的“1”是什么

    我想知道 1 在集合类型名称中意味着什么 例如 List 1 IList 1 有人知道那是什么吗 The backtick表示 泛型类型的名称以反引号 后跟数字结尾 表示泛型类型参数的数量 这样做的目的 名称重整是为了允许编译器支持泛型类型
  • Delphi定时器比毫秒更精确

    我在 Delphi 中有一个程序 它以 25 赫兹 每秒 25 次 的速度从外部应用程序获取帧 然后通过创建 1 2 个额外帧将其转换为 60 赫兹 每秒 60 帧 我需要通过连续构建帧缓冲区并从单独的线程输出帧来输出这些额外的帧 问题是
  • 读取存储在注册表中的 GUID 值

    我尝试读取存储为的 GUID 值binaryDelphi 注册表中的值 当我用BintoHex读取它时 但结果是相反的 看来我必须交换字节 但我认为 BinToHex 可以做到 我参考了这个线程 但找不到正确的解决方案 如何在 Delphi
  • .Net 支持柯里化泛型吗?

    假设我们有一个嵌套的泛型类 public class A
  • Java 中的泛型枚举

    我有一个基本的 Configuration 类 它在枚举中提供所有可能的键和相应值类型的类型 如下所示 public class Configuration public static enum Key FIRST KEY actual k
  • 创建无边框表单而不丢失 Windows 命令

    我已将表单更改为无边框表单 我只是更改了BorderStyle财产给bsNone 但现在我的应用程序失去了 Windows 锚点和一些命令 例如 WIN 对齐表单客户端 WIN 最小化表格 WIN 表格右对齐 WIN 表格左对齐 我尝试过设
  • 无法在 SAMSUNG GALAXY S7 EDGE 上调试

    为什么我无法在 RAD STUDIO 10 Seattle upd 1 中的 SAMSUNG GALAXY S7 EDGE ANDROID 6 0 1 上调试我的应用程序 当我调试时 设备上的应用程序启动 但 RAD STUDIO Delp
  • 安装软件包时出现无法加载软件包 %s 错误

    我正在 Delphi 2007 上进行测试 我的小组项目由 2 个包组成 包运行 bpl 它被标记为 仅运行时 并包含一个名为 uMyTestRun pas 的单元 其中定义了一个空的 TFrame 后代 unit uMyTestRun i
  • Delphi 中的非字母排序

    我正在尝试按特定顺序对字符串列表进行排序 我尝试用 B C A 来订购 而不是 A B C 我已经按照我需要的顺序声明了一个 const 数组 我尝试过 CustomSorte 但我不明白如何编写该函数 我现在正在尝试使用 for 循环 但
  • 我如何淡入/淡出 TImage?

    我有一个简单的TForm命名为Form1 Image1 是一个TImage加载了一个 PNGImage 和一个 Button1TButton测试事物 成功实现了对图像1的Alpha Blend的方法 代码如下 procedure SetPN
  • 如何在 iOS 和 Android 上获取应用程序恢复状态?

    当应用程序恢复时 是否可以从代码角度检查某些内容iOS and Android 例如当应用程序最小化并恢复时 应用程序仍在设备后台运行 你需要使用IFMX应用程序事件服务 http docwiki embarcadero com Libra
  • 类型映射时泛型属性的问题

    我有一个库 它导出类似于以下内容的实用程序类型 type Action
  • 如何获取已打开连接的套接字 ID/句柄/描述符? (.NET、C++、德尔福)

    我的问题已在标题中说明 我到底该怎么做呢 我有一个开放的连接 我想 劫持 它并通过它发送我的自定义消息 据我了解 这是通过套接字及其处理程序完成的 任何语言都可以 但首选 C NET 谢谢 UPDATE 我到底想要实现什么 我想为 post
  • Java:使用泛型实现对不同类型数字进行操作的类

    所以 假设我想编写一个对不同类型的数字进行操作的类 但我事先并不知道我将要对哪种数字 即整数 双精度数等 进行操作 我想使用泛型为这种情况创建一个通用类 就像是 Adder
  • T 为 type1 或 type2 的通用方法

    有没有办法声明一个泛型函数 泛型类型是type1or type2 example public void Foo
  • Delphi 生成的 Dylib 在 OSX 上的可靠部署

    我想在 OSX 上部署一个 dylib 它是用 Delphi 创建的 这个 dylib 应该是可由第三方应用程序加载 这看起来像是一个重复的问题 但经过大量搜索后 我找不到答案 这和这个是同一个问题 https forums embarca

随机推荐