2013-05-14 6 views
6

मैं निम्नलिखित कोडडेल्फी इंटरफेस जेनेरिक फ़ंक्शन - क्या कोई काम आसपास है?

IProxy<T> = interface 
    ['{1E3A98C5-78BA-4D65-A4BA-B6992B8B4783}'] 
    function Setup : ISetup<T>; 
    function Proxy : T; 
    function CastAs<I : IInterface> : IInterface; 
end; 

वहाँ संकलक त्रुटि है कि जब संकलन प्राप्त होता है के आसपास काम करने के लिए एक रास्ता है है?

"[डीसीसी त्रुटि] Delphi.Mocks.pas (123): E2535 इंटरफ़ेस तरीकों पैरामिट्रीकृत विधि नहीं चाहिए"

मूल रूप से

मैं इस इंटरफेस के आसपास पारित किया जा है और यह त्याग करने में सक्षम होना चाहते हैं, उस प्रकार के प्रकार में लौटने के लिए और उस प्रकार को लौटाकर। मैं इसे कक्षा के साथ प्राप्त कर सकता हूं, हालांकि एक इंटरफेस के चारों ओर गुजरना पसंद करेंगे।

अतिरिक्त जानकारी:

मैं निम्नलिखित वर्ग

TInterfaceProxy<T> = class(TBaseProxy<T>) 
private type 
    TProxyVirtualInterface = class(TVirtualInterface) 
    private 
    FProxy : TInterfaceProxy<T>; 
    protected 
    public 
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; override; stdcall; 
    constructor Create(AProxy : TInterfaceProxy<T>; AInterface: Pointer; InvokeEvent: TVirtualInterfaceInvokeEvent); 
    end; 
private 
    FVirtualInterfaces : TDictionary<TGUID, TProxyVirtualInterface>; 
protected 
    function InternalQueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall; 
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; override; 
    function Proxy : T;override; 
    function CastAs<I: IInterface> : I; 
public 
    constructor Create;override; 
    destructor Destroy;override; 
end; 

CastAs अच्छी तरह से यहाँ के रूप में नव अनुरोध किया डाली एक नया आभासी इंटरफेस बनाया जा सकता है काम करता है कहो। अब अगर मैं इस कक्षा को अपने जुर्माना से गुजरना चाहता हूं। हालांकि अगर मुझे इसे एक इंटरफ़ेस के रूप में आवश्यकता है यानी TInterfaceProxy<T> = class(TBaseProxy<T>, IProxy<T>) यह समझ में नहीं आता है। इसके साथ सहमत न हों, लेकिन समझें।

इसलिए मैं इस प्रतिबंध के आसपास कैसे हो सकता हूं ताकि मैं एक CastAs फ़ंक्शन को कॉल कर सकूं, किसी प्रकार में (किसी भी इंटरफ़ेस प्रकार से शुरू करने के लिए) पास कर सकूं, और इससे वर्चुअल इंटरफ़ेस तैयार कर सकूं?

उत्तर

12

इंटरफेस जेनेरिक पैरामीटरयुक्त विधियों का समर्थन नहीं करते हैं, क्योंकि संकलक कहते हैं।

कोई कामकाज नहीं है क्योंकि यह एक मौलिक सीमा है। वर्गों में पैरामीटरेटेड विधियों को कक्षा में प्रति तत्काल एक विधि जोड़कर कार्यान्वित किया जाता है। यह वर्गों के लिए काम करता है क्योंकि वे ठोस हैं, लेकिन इंटरफेस के लिए व्यवहार्य नहीं हैं। ऐसा इसलिए है क्योंकि इंटरफेस फ़ंक्शंस की एक तालिका है और उस तालिका का आकार भिन्न नहीं हो सकता है, इस पर निर्भर करता है कि कौन सा जेनेरिक विधि तत्काल कोड में कहीं और मौजूद होना है। इसी कारण से, जेनेरिक तरीके आभासी या गतिशील नहीं हो सकते हैं।

आपके प्रश्न में कोड थोड़ा सा गलत है।आप ने लिखा है:

function CastAs<I : IInterface> : IInterface; 

लेकिन मुझे यकीन है कि आप का मतलब कर रहा हूँ:

function CastAs<I : IInterface> : I; 

किसी भी मामले में, यह संभव नहीं है। एक विकल्प इसके बजाय कक्षा का उपयोग करना है। मैं मानता हूं कि यह एक बाध्य है।

आप एक अंतरफलक में यह करने के लिए चाहते हैं, तो सबसे अच्छा तुम कर सकते है:

function CastAs(const IID: TGUID): IInterface; 

लेकिन आप इसे इस तरह से कॉल करने के लिए होगा:

MyIntf := ProxyIntf.CastAs(IMyIntf) as IMyIntf; 

जो बेईमानी से कुछ हद तक लगता है ।

अपना जहर चुनें!

+0

धन्यवाद। मान लीजिए मुझे टिलिंग पास करने के लिए जाना होगा, और उसके साथ रहना होगा। क्लास को बाहरी रूप से एक्सपोज़र भी करेगा, लेकिन इंटरफ़ेस रखें "फ़ंक्शन कास्टए (कॉन्स आईआईडी: टीजीएल): IInterface;" अंदर का। इच्छा है कि मैं "आपकी भाषा में प्रोग्राम कर सकता हूं, इसमें नहीं" http://programmers.stackexchange.com/questions/2777/what-are-the-key-points-of-code-complete – Jason

+0

इसके अलावा हाँ ' कार्य CastAs : I; कोड को कॉपी करने पर मेरी गलती। – Jason

5

त्रुटि संदेश कहता है, एक इंटरफेस में एक विधि जेनेरिक पैरामीटर नहीं हो सकता है। संकलक बस इसे समर्थन नहीं करता है, और इस तरह के रूप में दर्ज है:

http://docwiki.embarcadero.com/RADStudio/XE4/en/Overview_of_Generics

इंटरफ़ेस में Parameterized विधि

एक पैरामिट्रीकृत विधि (विधि प्रकार पैरामीटर के साथ घोषित) में घोषित नहीं किया जा सकता एक इंटरफ़ेस

दूसरे शब्दों में, आपके CastAs विधि अवैध है क्योंकि इसे एक इंटरफ़ेस प्रकार में घोषित किया गया है। दूसरी तरफ, आपको पहली जगह ऐसी विधि की आवश्यकता नहीं है। आप एक इंटरफेस को दूसरे में कास्टिंग करने के लिए SysUtils.Supports() का उपयोग कर सकते हैं।

+0

सीधे समस्या को समझें, समझें। यह समझें कि कंपाइलर क्या कह रहा है, और डेल्फी के लिए यह क्यों एक मुद्दा है। डिज़ाइन से सहमत न हों, हालांकि डेल्फी की सीमाओं के आसपास काम करने के साथ मेरा डिज़ाइन क्यों करना है। वर्तमान में मैं सोच रहा हूं कि वस्तु को गुजरने का एकमात्र तरीका है। टिप्पणियों के लिए धन्यवाद। – Jason

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