2013-10-30 8 views
7

मैं वर्तमान में एक संकलन त्रुटि के साथ फंस गया हूं, हमारी कंपनी में कोई भी मदद नहीं कर सकता है और मुझे दुख की बात है कि एसओ या Google के लिए सही खोज पैटर्न नहीं मिल रहे हैं।डेल्फी - जेनेरिक के साथ इंटरफ़ेस विरासत

कोड के रूप में मैं 2 इंटरफेस, विरासत और 2 कक्षाओं का उपयोग कर रहा हूं, विरासत में मिला।

program Project22; 

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

'TKeyObjectStorage' के लिए संकलक त्रुटि है: निम्नलिखित कोड त्रुटि reproduces

[DCC Error] Project22.dpr(11): E2514 Type parameter 'T' must support interface 'IStorageObject'

मैं क्या लगता है, यह है कि संकलक पहचान नहीं कर रहा है कि क्लास 'TKeyObjectStorage के पैरामीटर टी 'सही ढंग से। यह सही होना चाहिए, क्योंकि वांछित प्रकार 'IKeyStorageObject' में मूल प्रकार IStorageObject है।

यह क्यों काम नहीं कर रहा है? मैं क्या गलत कर रहा हूं? क्या डेल्फी में यह संभव नहीं है?

+0

!!:

documentation इस मन आप को कवर करता है? क्या आपने उस अल्पविराम को सेमी-कोलन के रूप में बदल दिया था? !! और आपके द्वारा पोस्ट किया गया कोड अभी भी त्रुटि प्रदर्शित करने के लिए पर्याप्त नहीं है।कृपया जो मैंने सुझाया है और एक ** पूरा कार्यक्रम ** पोस्ट करें। मैंने आपको दिखाया कि मेरे जवाब में कैसे। –

+0

इस डेविड के लिए खेद है, हां मैंने किया, लेकिन ',' ने एक या यह त्रुटि नहीं फेंक दी और केवल मामूली निगरानी थी। फिर से सूखें। – Hugie

+0

@ हूजी, इस मूल समस्या से विचलित होने के लिए प्रश्न को न बदलें। किसी भी त्रुटि जो मूल में हैं, सवाल में रहने की जरूरत है; हालांकि इस मुद्दे को प्रदर्शित करने के लिए न्यूनतम कोड के साथ एक कंसोल ऐप बनाएं। और ** ** कंसोल ऐप को प्रश्न में पेस्ट करें। – Johan

उत्तर

9

अद्यतन

मूल प्रश्न एक समस्या जो मुझे पहचान (नीचे देखें) था। हालांकि, मैं जिस फिक्स का वर्णन करता हूं वह XE3 और बाद में ठीक है, लेकिन नीचे दिया गया प्रोग्राम XE2 में संकलित नहीं होता है। इस प्रकार मैंने निष्कर्ष निकाला कि यह एक एक्सई 2 जेनेरिक कंपाइलर बग है।

वैसे भी, यहाँ डेल्फी XE2 के लिए एक समाधान है:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>, IStorageObject> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IStorageObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

मूल जवाब

यह बेहतर होता यदि आप एक पूरा कार्यक्रम है कि संकलक त्रुटि प्रदर्शित मुहैया कराई थी । आपको उस त्रुटि को देखने के लिए किसी ऑब्जेक्ट को तुरंत चालू करने का प्रयास करना होगा।

लेकिन, मुझे लगता है कि मैंने आपकी समस्या का पुनरुत्पादन किया है। तो मेरा मानना ​​है कि इस मुद्दे को इस कोड है कि यह है कि:

TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = ... 

TKey और T दोनों को सामान्य बाधा लागू होता है। अब, स्पष्ट रूप से आप केवल बाधा T पर लागू करना चाहते हैं ताकि आप लिखने के लिए की आवश्यकता होगी:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

यह:

TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = ... 

यहाँ एक छोटी कार्यक्रम है कि में डेल्फी XE3 बदलाव के बाद संकलित है एक अर्ध-कॉलन के लिए एक अल्पविराम बदलना काफी बारीक है। महत्वपूर्ण विराम चिह्न द्वारा प्रोग्रामिंग कभी भी मजेदार नहीं है। उस ने कहा, आप औपचारिक पैरामीटर सूचियों में अल्पविराम और अर्ध-कॉलन के बीच के अंतर से परिचित हैं और इसलिए इसे यहां खींचे गए समान भेद को देखने के लिए आश्चर्य की बात नहीं आनी चाहिए। तुम सिर्फ पूरी तरह से प्रश्न में परिवर्तन किया था

Multiple Type Parameters

When you specify constraints, you separate multiple type parameters by semicolons, as you do with a parameter list declaration:

type 
    TFoo<T: ISerializable; V: IComparable> 

Like parameter declarations, multiple type parameters can be grouped together in a comma list to bind to the same constraints:

type 
    TFoo<S, U: ISerializable> ... 

In the example above, S and U are both bound to the ISerializable constraint.

+1

थैक्स डेविड, मैंने अपना कोड एक पूर्ण इकाई (बिना तात्कालिकता के) संपादित किया और यह एक स्वच्छ परियोजना में त्रुटि को पुन: उत्पन्न करता है। और हाँ, आप सही थे, मेरे पास मामूली तार्किक गलती थी, ->; लेकिन यह वह त्रुटि नहीं थी जिसके साथ मैं काम कर रहा हूं। आपके प्रयास के लिए Thx। – Hugie

+0

आपका अपडेट कोई त्रुटि उत्पन्न नहीं करता है। कोशिश करो। एक नई परियोजना के साथ शुरू करें, और उस इकाई को जोड़ें, और फिर संकलित करें। अनुमान लगाओ, यह संकलित करता है। जैसा कि मैंने अपने जवाब में कहा था, आपको किसी ऑब्जेक्ट को तुरंत चालू करने की आवश्यकता है। मैं इससे थोड़ा निराश हूं। आपको एसएससीसीई बनाने का तरीका सीखना है ताकि आप अपना समय बर्बाद न करें। मैं अब दोपहर के भोजन के लिए बंद हूँ। मुझे आशा है कि जब तक मैं वापस आऊंगा तब तक प्रश्न तय हो जाएगा। –

+1

मैंने आपके कोड को XE2 में कॉपी-पेस्ट किया है, यह अभी भी एक त्रुटि देता है: '[DCC त्रुटि] Project22.dpr (11): E2514 टाइप पैरामीटर 'टी' को इस पंक्ति पर इंटरफ़ेस 'IStorageObject''' का समर्थन करना चाहिए:' TKeyObjectStorage < TKey; टी: IKeyStorageObject > = वर्ग (TObjectStorage ) ' – Johan

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