2013-02-18 17 views
9

के रूप में कोई TInterfacedObject के साथ इंटरफ़ेस प्रकार पर ऑब्जेक्ट कास्टिंग करना मुझे कोई संदर्भ गिनती के साथ एक क्लास कार्यान्वयन इंटरफ़ेस की आवश्यकता नहीं है। मैंने निम्नलिखित किया:बेस क्लास

IMyInterface = interface(IInterface) 
     ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] 
     procedure InterfaceMethod; 
    end; 

    TMyClass = class(TObject, IMyInterface) 
    protected 
     function _AddRef: Integer;stdcall; 
     function _Release: Integer;stdcall; 
     function QueryInterface(const IID: TGUID; out Obj): HResult;stdcall; 
    public 
     procedure InterfaceMethod; 
    end; 

    procedure TMyClass.InterfaceMethod; 
    begin 
     ShowMessage('The Method'); 
    end; 

    function TMyClass.QueryInterface(const IID: TGUID; out Obj): HResult; 
    begin 
     if GetInterface(IID, Obj) then 
      Result := 0 
     else 
      Result := E_NOINTERFACE; 
    end; 

    function TMyClass._AddRef: Integer; 
    begin 
     Result := -1; 
    end; 

    function TMyClass._Release: Integer; 
    begin 
     Result := -1; 
    end; 

संदर्भ गणना की कमी ठीक काम करती है। लेकिन मेरी चिंता यह है कि मैं as ऑपरेटर का उपयोग IMyInterface को TMyClass डाली नहीं कर सकता है:

var 
    MyI: IMyInterface; 
begin 
    MyI := TMyClass.Create as IMyInterface; 

मैं

[डीसीसी त्रुटि] E2015 ऑपरेटर लागू नहीं दिया हूँ इस संकार्य प्रकार के

समस्या तब गायब हो जाती है जब TMyClassTInterfacedObject से निकला - यानी मैं कंपाइलर त्रुटि के बिना ऐसा कास्टिंग कर सकता हूं। जाहिर है, मैं बेस श्रेणी के रूप में TInterfacedObject का उपयोग नहीं करना चाहता क्योंकि यह मेरी कक्षा संदर्भ गिना जाएगा। इस तरह के कास्टिंग को अस्वीकार क्यों किया जाता है और यह कैसे काम करेगा?

+0

आपके इंटरफ़ेस घोषणा में GUID जोड़कर आपके पास बेहतर परिणाम हो सकते हैं। '= इंटरफेस 'लाइन के बाद एक नई लाइन जोड़ें और Ctrl-Shft-G दबाएं। 'as',' GetInterface' और 'support' आदि को काम करने के लिए GUID द्वारा इंटरफ़ेस की पहचान करने में सक्षम होना आवश्यक है। –

+0

आपने मेरी पोस्ट को ध्यान से नहीं पढ़ा। जब मैं TInterfacedObject से प्राप्त करता हूं तो यह काम करता है। GUID के पास यहां कुछ भी नहीं है। COM के साथ काम करने के लिए आपको केवल GUID की आवश्यकता है। –

+0

हम्म, जो डेल्फी संस्करण है? –

उत्तर

14

कारण आप अपने कोड में as का उपयोग नहीं कर सकते हैं कि आपकी कक्षा स्पष्ट रूप से समर्थित इंटरफेस की सूची में IInterface सूचीबद्ध नहीं करती है। भले ही आपका इंटरफ़ेस IInterface से प्राप्त हो, भले ही आप वास्तव में उस इंटरफ़ेस को सूचीबद्ध न करें, आपकी कक्षा इसका समर्थन नहीं करती है।

तो, तुच्छ ठीक इस तरह अपनी कक्षा घोषित करने के लिए है:

TMyClass = class(TObject, IInterface, IMyInterface) 

कारण यह है कि अपनी कक्षा IInterface को लागू करने की जरूरत है क्या संकलक आदेश as कलाकारों को लागू करने में पर भरोसा कर रहा है।

दूसरा बिंदु मैं बनाना चाहता हूं कि आपको सामान्य रूप से इंटरफ़ेस विरासत का उपयोग करने से बचें। बड़े पैमाने पर यह थोड़ा उद्देश्य प्रदान करता है। इंटरफेस का उपयोग करने के लाभों में से एक यह है कि आप एकल विरासत बाधा से मुक्त हैं जो कार्यान्वयन विरासत के साथ आता है।

लेकिन किसी भी मामले में, सभी डेल्फी automatically inherit from IInterface इंटरफेस करते हैं, इसलिए आपके मामले में यह निर्दिष्ट करने का कोई मतलब नहीं है। मैं इस तरह आपका इंटरफ़ेस घोषित करूंगा:

IMyInterface = interface 
    ['{B84904DF-9E8A-46E0-98E4-498BF03C2819}'] 
    procedure InterfaceMethod; 
end; 

अधिक व्यापक रूप से आपको अपने इंटरफेस के साथ विरासत का उपयोग न करने का प्रयास करना चाहिए। उस दृष्टिकोण को लेकर आप कम युग्मन को प्रोत्साहित करेंगे और इससे अधिक लचीलापन होता है।

+0

इंटरफेस विरासत ** ** ** कार्यान्वयन विरासत नहीं है। डेल्फी में भी कोई इंटरफ़ेस 'IInterface' से लिया गया है। अंतिम वाक्य अस्पष्ट है। – kludg

+0

@ सर्ग वह इंटरफ़ेस विरासत ** नहीं ** कार्यान्वयन विरासत ठीक उसी बिंदु है जिसे मैं बनाने की कोशिश कर रहा हूं। मैं कोशिश करूँगा और इसे साफ़ कर दूंगा। स्पष्टीकरण के लिए –

+1

धन्यवाद। अब मुझे यह स्पष्ट और स्पष्ट लगता है :) –

संबंधित मुद्दे