सं
सबसे पहले, वहाँ एक जैसी कोई चीज नहीं है "गैर instantiated चर।" आप इसे अपना नाम टाइप करने और अपनी स्रोत फ़ाइल में टाइप करने के केवल कार्य द्वारा तुरंत चालू करते हैं।
दूसरा, आप पहले से ही जानते हैं कि एक वैरिएबल के बारे में जानना आपके स्रोत कोड में देखकर है। एक बार आपके प्रोग्राम को संकलित करने के बाद परिवर्तनीय मौजूद है। उसके बाद, यह सब सिर्फ बिट्स है।
एक सूचक केवल संकलन समय पर एक प्रकार है। रन टाइम पर, उस पते पर जो भी किया जा सकता है, वह पहले ही निर्धारित हो चुका है। इसके लिए कंपाइलर जांच करता है, जैसा कि आपने पहले ही नोट किया है। रन टाइम पर एक चर के प्रकार की जांच करना केवल उन भाषाओं में उपयोगी होता है जहां गतिशील भाषाओं में एक चर का प्रकार बदल सकता है। निकटतम डेल्फी इसके Variant
प्रकार के साथ आता है। चर का प्रकार हमेशा Variant
है, लेकिन आप इसमें कई प्रकार के मान स्टोर कर सकते हैं। यह पता लगाने के लिए कि आप क्या रखते हैं, आप VarType
फ़ंक्शन का उपयोग कर सकते हैं।
किसी भी समय आप एक चर के साथ जुड़े प्रकार की प्रकार की जानकारी प्राप्त करने के लिए TypeInfo
का उपयोग करना चाहते हैं, तो आप सीधे उस प्रकार का नाम भी दे सकते हैं जिसमें आप रुचि रखते हैं; यदि चर दायरे में है, तो आप इसकी घोषणा पा सकते हैं और घोषित प्रकार का उपयोग अपने कॉल में TypeInfo
पर कर सकते हैं।
यदि आप किसी फ़ंक्शन में मनमाने ढंग से पता करना चाहते हैं और उस फ़ंक्शन को स्वयं के लिए प्रकार की जानकारी मिलती है, तो आप भाग्य से बाहर हैं। आपको इसके अतिरिक्त PTypeInfo
मान को अतिरिक्त पैरामीटर के रूप में पास करने की आवश्यकता होगी। यही वह अंतर्निहित डेल्फी कार्य करता है। उदाहरण के लिए, जब आप पॉइंटर चर पर New
पर कॉल करते हैं, तो संकलक एक अतिरिक्त पैरामीटर डालता है जिसमें आपके द्वारा आवंटित किए जाने वाले प्रकार के लिए PTypeInfo
मान होता है। जब आप गतिशील सरणी पर SetLength
पर कॉल करते हैं, तो कंपाइलर सरणी प्रकार के लिए PTypeInfo
मान डालता है।
The answer that you gave सुझाव देता है कि आप जो कुछ भी मांगे उसके अलावा कुछ और ढूंढ रहे हैं।अपने प्रश्न को देखते हुए, मैंने सोचा था कि आप एक काल्पनिक समारोह है कि इस कोड को पूरा कर सके देख रहे थे:
function GetVariableTypeInfo(pvar: Pointer): PTypeInfo;
begin
if not Assigned(pvar) then
Result := nil
else if IsClass(PPointer(pvar)^) then
Result := PClass(pvar).ClassInfo
else if IsObject(PPointer(pvar)^) then
Result := PObject(pvar).ClassInfo
else
raise EUnknownResult.Create;
end;
यह स्पष्ट रूप से S
लिए काम नहीं करेगा:
var
S: string;
Instance: IObjectType;
Obj: TDBGrid;
Info: PTypeInfo;
begin
Info:= GetVariableTypeInfo(@S);
Assert(Info = TypeInfo(string));
Info:= GetVariableTypeInfo(@Instance);
Assert(Info = TypeInfo(IObjectType));
Info:= GetVariableTypeInfo(@Obj);
Assert(Info = TypeInfo(TDBGrid));
end;
के IsClass
and IsObject
functions from the JCL का उपयोग करें कि समारोह के निर्माण के लिए करते हैं या Instance
ऊपर है, लेकिन देखते हैं क्या Obj
साथ होता है:
Info := GetVariableTypeInfo(@Obj);
कि एक पहुँच देना चाहिए उल्लंघन। Obj
का कोई मूल्य नहीं है, इसलिए IsClass
और IsObject
दोनों एक अनिर्दिष्ट स्मृति पता पढ़ रहे होंगे, शायद आपकी प्रक्रिया से संबंधित कोई भी नहीं। आपने एक दिनचर्या मांगी है जो एक चर के पते को अपने इनपुट के रूप में उपयोग करेगी, लेकिन केवल पता पर्याप्त नहीं है।
अब आइए देखें कि कैसे IsClass
और IsObject
वास्तव में व्यवहार करते हैं। वे कार्य एक मनमाना मूल्य लेते हैं और जांचते हैं कि मूल्य जैसा दिखता है, यह किसी भी प्रकार का ऑब्जेक्ट (उदाहरण) या कक्षा का मान हो सकता है। इस तरह यह प्रयोग करें:
// This code will yield no assertion failures.
var
p: Pointer;
o: TObject;
a: array of Integer;
begin
p := TDBGrid;
Assert(IsClass(p));
p := TForm.Create(nil);
Assert(IsObject(p));
// So far, so good. Works just as expected.
// Now things get interesting:
Pointer(a) := p;
Assert(IsObject(a));
Pointer(a) := nil;
// A dynamic array is an object? Hmm.
o := nil;
try
IsObject(o);
Assert(False);
except
on e: TObject do
Assert(e is EAccessViolation);
end;
// The variable is clearly a TObject, but since it
// doesn't hold a reference to an object, IsObject
// can't check whether its class field looks like
// a valid class reference.
end;
सूचना है कि कार्यों आप चर के बारे में कुछ भी नहीं, केवल मूल्यों वे पकड़ के बारे में बताओ। एक चर के बारे में प्रकार की जानकारी कैसे प्राप्त करें, इस सवाल का जवाब देने के लिए, मैं उन कार्यों को वास्तव में नहीं मानूंगा।
इसके अलावा, आपने कहा है कि आप चर के बारे में जो कुछ जानते हैं उसका पता है। आपके द्वारा मिले कार्यों को एक चर का पता नहीं लेते हैं। वे एक चर के मूल्य लेते हैं।
var
c: TClass;
begin
c := TDBGrid;
Assert(IsClass(c));
Assert(not IsClass(@c)); // Address of variable
Assert(IsObject(@c)); // Address of variable is an object?
end;
मैं कैसे गुजर जो स्पष्ट रूप से उन्हें में कचरा है द्वारा इन कार्यों कोस रहा हूँ करने के लिए आप पर आपत्ति हो सकती है: यहाँ एक प्रदर्शन है। लेकिन मुझे लगता है कि केवल इस विषय के बारे में बात करने के लिए समझ में आता है। यदि आप जानते हैं कि आपके पास कचरा मूल्य कभी नहीं होगा, तो आपको उस फ़ंक्शन की आवश्यकता नहीं है जिसे आप किसी भी तरह से पूछ रहे हैं क्योंकि आप अपने चर के लिए वास्तविक प्रकारों का उपयोग करने के लिए पहले से ही अपने प्रोग्राम के बारे में पर्याप्त जानते हैं।
कुल मिलाकर, आप गलत सवाल पूछ रहे हैं। यह पूछने के बजाय कि आप एक चर के प्रकार या स्मृति में किसी प्रकार के मान को निर्धारित करते हैं, आपको यह पूछना चाहिए कि आप अपने आप को उस स्थिति में कैसे प्राप्त कर चुके हैं जहां आप पहले से ही अपने चर के प्रकार और आपके डेटा नहीं जानते हैं।
आपके पास "प्रक्रिया परीक्षण (var AUntypedParam)" (या "var" के बजाय "const" या "out" के साथ) हो सकता है। –
क्षमा करें। मेरा जवाब "untyped सूचक" के बजाय "untyped पैरामीटर" कहा जाना चाहिए था। सही किया। –