技巧:利用RTTI设置缺省属性值(50分)

  • 主题发起人 主题发起人 shenloqi
  • 开始时间 开始时间
S

shenloqi

Unregistered / Unconfirmed
GUEST, unregistred user!
这两天因为要准备求职,整理了一下Object Pascal的有关东西,就与大家共享了。

Delphi的RTTI里藏了不少好东西:)
下面这个过程将对象作为参数,并查找所有的顺序类型属性,然后获得这些属性的缺省值
并把属性值设为缺省的。可以从构造函数调用这个函数,以保证属性被正确的初始化,从
而避免出现属性声明具有一个缺省值,而构造函数却有另一个不同的缺省值。

要获得进一步的了解请参见TypInfo.pas。

代码:
procedure SetDefaultValues(AObj: TObject);
const
  //TypInfo.pas中定义了这些TTypeKind。
  //TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
  //  tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
  //  tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);
  //
  //具有附加的类型数据的类型为:
  //tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass,
  //tkMethod, tkWChar, tkInterface, tkInt64
  //
  tkOrdinal = [tkEnumeration, tkInteger, tkChar, tkSet, tkWChar];
  //因为用nodefault指示字(与省略Default效果一样)的话,Delphi将$8000000
  //(最小负整数)储存为缺省值
  NoDefault = Low(Integer);
var
  //关于PPropInfo与PPropList,TypInfo.pas中如此定义:
  //PPropInfo = ^TPropInfo;
  //TPropInfo = packed record
  //  PropType: PPTypeInfo;
  //  GetProc: Pointer;
  //  SetProc: Pointer;
  //  StoredProc: Pointer;
  //  Index: Integer;
  //  Default: Longint;
  //  NameIndex: SmallInt;
  //  Name: ShortString;
  //end;
  //
  //TPropInfoProc = procedure(PropInfo: PPropInfo) of object;
  //PPropList = ^TPropList;
  //TPropList = array[0..16379] of PPropInfo;
  //
  PropList: PPropList;
  Count, I: Integer;
  Value: Integer;
begin
  //获得可能的有默认值的顺序属性数目
  Count := GetPropList(AObj, tkOrdinal, nil);
  //分配内存来存放属性信息
  GetMem(PropList, Count * SizeOf(PPropInfo));
  try
    //GetPropList函数获取按字母顺序排列的指向对象匹配属性的PPropList指针
    //的列表,并返回存储在PropList中的属性数目的一个计数。传递nil给
    //PropList参数可以获取匹配属性数目的计数。
    GetPropList(AObj, tkOrdinal, PropList);
    //循环,如果有默认值则给这个属性赋值为默认值
    for i := 0 to Count-1 do
      if PropList[I].Default <> NoDefault then
        //SetOrdProp设置任何顺序类型属性的值,如集合,对象,字符,
        //枚举或者整数属性。
        SetOrdProp(AObj, PropList[I], PropList[I].Default)
  finally
    //释放内存
    FreeMem(PropList);
  end;
end;
 
学习,这个shenloqi真是个好人啊
 
又是个undocumented的吧!!!

好好学习,天天向上!
 
这和国外的某网站上一模一样,你还是把那个网址贴出来吧[:D]
 
楼上的,准确地说这是经过我的查阅相关书籍之后按照他的代码以及我的理解贴出来的。
我想这样的话,应该更加容易看懂以及理解了吧:)
(不过我相信国外的站点上肯定有这些知识的,我觉得国外的Delphi高手真的很牛)
 
shenloqi:
呵呵呵,不错,我很佩服你把中文注释做的那么齐全,向你学习![:D]
 
学习+感谢
 
谢谢 shenloqi。RTTI 真是非常有用。下面这篇文章是 RTTI 的一种应用:
http://community.borland.com/article/0,1410,28551,00.html
 
孙老师给的那片帖子讲的很好,因为我现在换工作,不能够仔细的研究它了,等将来研究
了一定程度了,一定把它翻译出来给大家共享。
 
多人接受答案了。
 
后退
顶部