Delphi 对于静态数组,使用RTTI获取记录字段类型失败

Delphi 对于静态数组,使用RTTI获取记录字段类型失败,delphi,rtti,delphi-10-seattle,Delphi,Rtti,Delphi 10 Seattle,我正在尝试获取记录字段的类型,以便创建正确的比较器(作为任何/几乎任何记录类型的通用解决方案)。我找不到静态数组的类型信息: TArrFieldTest = record a: string; b: array[0..3] of byte; end; procedure Test; var rttiContext: TRttiContext; rttiType: TRttiType; rttiFields: TArray<TRttiField>;

我正在尝试获取记录字段的类型,以便创建正确的比较器(作为任何/几乎任何记录类型的通用解决方案)。我找不到静态数组的类型信息:

  TArrFieldTest = record
    a: string;
    b: array[0..3] of byte;
  end;

procedure Test;
var
  rttiContext: TRttiContext;
  rttiType: TRttiType;
  rttiFields: TArray<TRttiField>;
begin
  rttiType := rttiContext.GetType(TypeInfo(TArrFieldTest));
  rttiFields := rttiType.GetFields;
  Assert(rttiFields[0].FieldType<>nil); // it's ok
  Assert(rttiFields[1].FieldType<>nil); // fail here!
end;
TArrFieldTest=记录
a:弦;
b:字节数组[0..3];
结束;
程序测试;
变量
rttiContext:TRttiContext;
rttType:trtType;
RTT场:焦油;
开始
rttiType:=rttiContext.GetType(TypeInfo(TArrFieldTest));
rttiFields:=rttiType.GetFields;
断言(rttiFields[0].FieldTypenil);//没关系
断言(rttiFields[1].FieldTypenil);//在这里失败!
结束;
对于任何类型的静态数组,FieldType为nil。 你知道这里怎么了吗?
或者,可能有更简单的方法来创建用于TArray/TDictionary等的记录的比较器

为了使RTTI可用,您需要声明一个类型。例如:

type
  TMyStaticArrayOfByte = array[0..3] of byte;

  TArrFieldTest = record
    a: string;
    b: TMyStaticArrayOfByte;
  end;

有关动态数组的信息不需要单独类型的声明。在静态数组的情况下,我们必须声明单独的类型,这是唯一的方法吗?没有我想象的那么好,但总比没有好,谢谢!动态数组是一种编译器管理的类型,具有自己的RTTI,并且包含动态数组的RTTI链接到的具有自己RTTI的不同类型的元素。静态数组不是类型,因此没有RTTI,除非您将其设置为类型,否则它只是一个内存块如果要使用RTTI访问数组中的项。@Remy我指的是普通动态数组(不是变体),所有元素的类型都是相同的(“TArray”或“T数组”)。您解释了一些内部结构,这很好,但我认为“字节的a:array[0..0]和“字节的a:array”只是声明类型的不同方式。这两个都是类型定义,我无法想象为什么Delphi只支持其中一个。它限制了为流媒体等编写通用解决方案的能力。托管类型在这里不是边界,支持大多数非托管类型,但不支持静态数组。小更新:对于托管类型的静态数组(“字符串的数组[0..1]),可以检索RTTI。短字符串类型也是如此(大卫·赫弗南的解决方案也适用于他们)。