سؤال
أحاول تحليل الكائنات إلى XML في دلفي، لذلك قرأت عن استدعاء طريقة ClassInfo للكائن للحصول على معلومات RTTI الخاصة به.
الأمر هو أن هذا يعمل على ما يبدو فقط مع كائنات TPersistent.بخلاف ذلك، لا بد لي من إضافة توجيه المترجم {$M+} على وجه التحديد إلى الكود المصدري للمترجم لإنشاء معلومات RTTI.
لذلك أضفت التوجيه بسعادة، فقط لأجد أنه حتى لو قام بإرجاع شيء ما من استدعاء ClassInfo (كان يستخدم لإرجاع لا شيء)، فلا يمكنني الآن استرداد خصائص الفصل أو الحقول أو الأساليب منه.يبدو الأمر كما لو أنه خلق الكائن فارغًا.
هل لديك أي فكرة عما أفتقده هنا؟شكرًا!
المحلول
هل وضع تلك الخصائص والأساليب في مقطع published
؟
وبالاضافة الى ذلك، 'الكلاسيكية' RTTI ($ TYPEINFO ON) سيحصل فقط لك معلومات عن الخصائص، وليس على الطرق. تحتاج "مدد" RTTI ($ METHODINFO ON) لهؤلاء.
ونقطة انطلاق جيدة لتمديد RTTI: ديفيد غلاسبورو على الموسعة RTTI
و(الذي نعتقد أن هذا مجرد دقيقة انتهيت من كتابة بعض التعليمات البرمجية التي تستخدم الموسعة RTTI وقررت لتصفح المكدس تجاوز قليلا:))
نصائح أخرى
سوف تظهر لك RTTI فقط نشرت خصائص، الخ.- وليس العامة فقط.
جرب الكود الخاص بك باستخدام TObject وشاهد ما سيحدث - إذا لم ينجح ذلك، انشر الكود الخاص بك لأنه ليس الجميع نفسيين.
هل تعتبر باستخدام المكون TXMLDocument؟ وسوف ننظر في XML الخاصة بك ومن ثم إنشاء وحدة لطيفة من دروس دلفي الذي يمثل ملف XML الخاصة بك - يجعل حقا، حقا من السهل قراءة وكتابة ملفات XML
وأما بالنسبة لمشكلة RttiType العودة لا شيء فقط، وهذا ربما يحدث لسبب واحد: في الاختبار، هل لا مثيل الطبقة في أي وقت. مترجم، لأنه لم يوجد إشارة إلى هذه الفئة (لأنه ليس مثيل على الإطلاق)، يزيل بكل بساطة من المعلومات كشكل من أشكال الأمثل. راجع الأمثلة اثنين أدناه. والسلوك يختلف عندما يكون لديك الطبقة إنشاء مثيل عند نقطة معينة في التعليمات البرمجية أم لا.
لنفترض أن الطبقة التالية:
type
TTest = class
public
procedure Test;
end;
والتعليمات البرمجية التالية أدناه:
var
LContext: TRttiContext;
LType: TRttiType;
LTest: TTest;
begin
LContext := TRttiContext.Create;
for LType in LContext.GetTypes do
begin
if LType.IsInstance then
begin
WriteLn(LType.Name);
end;
end;
end;
وحتى الآن، معلومات فئة TTEST ليست متاحة للاستخدام من قبل RTTI. ومع ذلك، عندما نخلق في مرحلة ما، ضمن التطبيق، ثم يتم إنشاء إشارة لذلك في الترجمة، الأمر الذي يجعل هذه المعلومات:
var
LContext: TRttiContext;
LType: TRttiType;
LTest: TTest;
begin
LTest := TTest.Create; //Here i´m using TTest.
//Could be in another part of the program
LContext := TRttiContext.Create;
for LType in LContext.GetTypes do
begin
if LType.IsInstance then
begin
WriteLn(LType.Name);
end;
end;
end;
وعند هذه النقطة، إذا كنت تستخدم على LContext.FindType ( 'TTEST') ، أو لن يكون هناك عودة معدومة، لأن المترجم تبقى الإشارة إلى الفئة. وهذا ما يفسر السلوك قد تواجهك في الاختبارات الخاصة بك.