2013-02-20 9 views

उत्तर

72

हमें निम्नलिखित तीन प्रकार घोषणाओं पर विचार करें:

TProcedure = procedure; 
TMethod = procedure of object; 
TAnonMethod = reference to procedure; 

ये सभी एक दूसरे के बहुत समान हैं। इन तीनों में से प्रत्येक के कॉलिंग उदाहरणों के मामले में, कॉलिंग कोड समान है। इन प्रकारों के चर के लिए क्या आवंटित किया जा सकता है में मतभेद उत्पन्न होते हैं।

प्रक्रियात्मक प्रकार

TProcedure एक procedural type है।

procedure MyProcedure; 
begin 
end; 

यह एक गैर वस्तु उन्मुख प्रक्रिया है: आप प्रकार का एक चर करने के लिए इस फार्म के TProcedure कुछ प्रदान कर सकते हैं। आप TProcedure चर के लिए एक उदाहरण या कक्षा विधि असाइन नहीं कर सकते हैं। हालांकि, आप static class method को TProcedure चर पर असाइन कर सकते हैं।

विधि संकेत

TMethod एक method pointer है। यह of object की उपस्थिति से संकेत मिलता है। आप प्रकार का एक चर है जब आप TMethod असाइन करना होगा या तो:

  1. एक instantiated वस्तु का एक उदाहरण विधि, या
  2. एक वर्ग विधि।

तो तुम इनमें से किसी असाइन कर सकते हैं:

procedure TMyClass.MyMethod; 
begin 
end; 

class procedure TMyClass.MyClassMethod; 
begin 
end; 

एक प्रक्रियात्मक प्रकार और एक विधि सूचक के बीच बड़ा अंतर है कि बाद के दोनों कोड और डेटा का संदर्भ होता है है। एक विधि सूचक अक्सर दो-सूचक प्रक्रियात्मक प्रकार के रूप में जाना जाता है। एक वेरिएबल जिसमें एक विधि सूचक शामिल होता है, कोड और संदर्भ/कक्षा को कॉल करने के लिए संदर्भ देता है।

var 
    instance1, instance2: TMyClass; 
    method1, method2: TMethod; 
.... 
method1 := instance1.MyMethod; 
method2 := instance2.MyMethod; 

अब, हालांकि method1 और method2 कोड के एक ही हिस्से को देखें, वे अलग वस्तु उदाहरणों के साथ जुड़े रहे:

निम्नलिखित कोड पर विचार करें। तो, अगर हम

method1(); 
method2(); 

फोन हम दो अलग-अलग मामलों पर MyMethod लागू कर रहे हैं।

instance1.MyMethod(); 
instance2.MyMethod(); 

बेनामी तरीकों

अंत में हम anonymous methods के लिए आते हैं: यह कोड के बराबर है। प्रक्रियात्मक प्रकारों और विधि संकेतकों की तुलना में ये अधिक सामान्य उद्देश्य हैं। आप reference to सिंटैक्स का उपयोग करके परिभाषित चर के लिए निम्न में से कोई भी असाइन कर सकते हैं:

  1. एक सादा गैर ऑब्जेक्ट-उन्मुख प्रक्रिया।
  2. तत्काल कक्षा का एक उदाहरण विधि।
  3. एक कक्षा विधि।
  4. एक अज्ञात विधि।

उदाहरण के लिए:

var 
    AnonMethod: TAnonMethod; 
.... 
AnonMethod := MyProcedure;   // item 1 above 
AnonMethod := instance1.MyMethod;  // item 2 
AnonMethod := TMyClass.MyClassMethod; // item 3 

बेनामी तरीकों, ऊपर आइटम 4, उन में लाइन अपने कोड में किया गया है। उदाहरण के लिए:

var 
    AnonMethod: TAnonMethod; 
.... 
AnonMethod := procedure 
    begin 
    DoSomething; 
    end; 

गुमनाम तरीकों का सबसे बड़ा लाभ जब प्रक्रियात्मक प्रकार और विधि संकेत की तुलना में है कि वे variable capture के लिए अनुमति देते हैं। उदाहरण के लिए विचार करना वर्णन करने के लिए निम्नलिखित लघु कार्यक्रम:

{$APPTYPE CONSOLE} 
program VariableCapture; 

type 
    TMyFunc = reference to function(X: Integer): Integer; 

function MakeFunc(Y: Integer): TMyFunc; 
begin 
    Result := function(X: Integer): Integer 
    begin 
     Result := X*Y; 
    end; 
end; 

var 
    func1, func2: TMyFunc; 

begin 
    func1 := MakeFunc(3); 
    func2 := MakeFunc(-42); 
    Writeln(func1(4)); 
    Writeln(func2(2)); 
    Readln; 
end. 

यह है निम्नलिखित उत्पादन:

 
12 
-84 
+12

मैं क्यों पता था कि यह आप था इससे पहले कि मैं नीचे करने के लिए मिल गया? –

+1

@ मारजन वेनेमा शायद इसलिए कि डेविड बहुत कम लोगों में से एक है जो भारी व्याख्या देते हैं, मूल रूप से एसओ पर डेल्फी टैग के लिए एक बिल्डिंग ब्लॉक ( – ComputerSaysNo

+5

@ कंप्यूटर प्लेयर नहीं, धन्यवाद, लेकिन जब आप कहते हैं कि मैं आपसे पूरी तरह से सहमत नहीं हूं " बहुत कम "। मुझे लगता है कि एसओ पर सक्रिय डेल्फी उत्तरदाताओं की अच्छी संख्या है जो अच्छे स्पष्टीकरण के साथ जवाब देते हैं। मैं नामों का नाम नहीं रखूंगा, लेकिन हम में से जो लोग यहां सक्रिय हैं वे जानते हैं कि वे कौन हैं। हमें सभी को प्रोत्साहित करना चाहिए , हमारे मतदान के माध्यम से, स्पष्टीकरण के साथ उत्तर। –

6

पहले anonymous method है की का उपयोग

TFuncOfIntToString = reference to function(x: Integer): string; 

और

TFuncOfIntToString = function(x: Integer): string of object; 

के बीच का अंतर है, दूसरा साधारण method है।