delphi – 如何获取类型集的任何变量的元素数量?
发布时间:2020-12-15 04:06:50 所属栏目:大数据 来源:网络整理
导读:AFAIK没有内置功能.在网上搜索我发现这个 function并且它适用于我,但我不喜欢使用它,因为它是汇编而我无法理解它在做什么.所以我写了这个函数也有效: function Cardinality(const PSet: PByteArray; const SizeOfSet(*in bytes*): Integer): Integer;const
AFAIK没有内置功能.在网上搜索我发现这个
function并且它适用于我,但我不喜欢使用它,因为它是汇编而我无法理解它在做什么.所以我写了这个函数也有效:
function Cardinality(const PSet: PByteArray; const SizeOfSet(*in bytes*): Integer): Integer; const Masks: array[0..7] of Byte = (1,2,4,8,16,32,64,128); var I,J: Integer; begin Result := 0; for I := 0 to SizeOfSet - 1 do for J := 0 to 7 do if (PSet^[I] and Masks[J]) > 0 then Inc(Result); end; 现在,我想知道我是否可以依赖这个功能?或者也许设置数据类型背后有一个技巧,这就是德尔福没有内置方法的原因. 但如果我的功能可靠,那么我该如何改进它: >将常量传递给它 我想把它称为Cardinality(AnySet)而不是Cardinality(@AnySet,SizeOf(TAnySet)). 顺便说一句,我需要在XE和XE5中编译它. 解决方法
您可以使用泛型和RTTI实现此功能.像这样:
uses SysUtils,TypInfo; type ERuntimeTypeError = class(Exception); TSet<T> = class strict private class function TypeInfo: PTypeInfo; inline; static; public class function IsSet: Boolean; static; class function Cardinality(const Value: T): Integer; static; end; const Masks: array[0..7] of Byte = (1,128); implementation { TSet<T> } class function TSet<T>.TypeInfo: PTypeInfo; begin Result := System.TypeInfo(T); end; class function TSet<T>.IsSet: Boolean; begin Result := TypeInfo.Kind=tkSet; end; function GetCardinality(const PSet: PByteArray; const SizeOfSet(*in bytes*): Integer): Integer; inline; var I,J: Integer; begin Result := 0; for I := 0 to SizeOfSet - 1 do for J := 0 to 7 do if (PSet^[I] and Masks[J]) > 0 then Inc(Result); end; class function TSet<T>.Cardinality(const Value: T): Integer; var EnumTypeData: PTypeData; begin if not IsSet then raise ERuntimeTypeError.Create('Invalid type in TSet<T>,T must be a set'); Result := GetCardinality(PByteArray(@Value),SizeOf(Value)); end; 用法: Writeln(TSet<SomeSet>.Cardinality(Value)); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |