2009-11-11 10 views
6

असल में, मैं चाहता हूं कि एक वर्ग एक ही सामान्य इंटरफेस के दो अलग-अलग संस्करणों को लागू करने में सक्षम हो।जेनिक्स मेस अप इंटरफेस नाम मैपिंग करें?

इस कोड

type 
    // a generic interface 
    ITest<T> = interface 
    ['{6901FE04-8FCC-4181-9E92-85B73264B5DA}'] 
    function Val: T; 
    end; 

    // a class that purports to implement two different types of that interface 
    TTest<T1, T2> = class(TInterfacedObject, ITest<T1>, ITest<T2>) 
    protected 
    fV1: T1; 
    fV2: T2; 
    public 
    constructor Create(aV1: T1; aV2: T2); 
    function Val: T1;    // Val() for ITest<T1> 
    function T2Val: T2;    // Val() for ITest<T2> 
    function ITest<T2>.Val = T2Val; // mapping 
    end; 

constructor TTest<T1, T2>.Create(aV1: T1; aV2: T2); 
begin 
    inherited Create; 
    fV1 := aV1; 
    fV2 := aV2; 
end; 

function TTest<T1, T2>.T2Val: T2; 
begin 
    result := fV2; 
end; 

function TTest<T1, T2>.Val: T1; 
begin 
    result := fV1; 
end; 

///////////// 
procedure Test; 
var 
    t : TTest<integer, string>; 
begin 
    t := TTest<integer, string>.Create(39, 'Blah'); 
    ShowMessage((t as ITest<string>).Val);   // this works as expected 
    ShowMessage(IntToStr((t as ITest<integer>).Val)); // this gets AV 
end; 

पहले ShowMessage प्रदर्शित करता है 'ब्ला' के रूप में मैं उम्मीद होती है, लेकिन दूसरी दुर्घटनाओं पर विचार करें। इसका कारण यह है कि कॉल वैल() के बजाय T2Val() को आमंत्रित करता है जैसा कि मैंने अपेक्षा की थी। स्पष्ट रूप से संघर्ष समाधान मैपिंग दोनों प्रकार के इंटरफेस के लिए विधि को मानचित्र करता है न केवल आईटीएस्ट के लिए: टी 2।

तो, यहां मेरा प्रश्न है।

क्या यह एक बग है? जिसका मतलब है, क्या एम्बरकाडेरो ने इसका समर्थन करने का इरादा किया और इसे गलत तरीके से कार्यान्वित किया? या क्या प्रोग्रामर को ऐसा कुछ करने की इजाजत देने का कोई इरादा नहीं था? (ईमानदारी से, मैं थोड़ा आश्चर्यचकित था कि मेरा परीक्षण कार्यक्रम भी संकलित)

यदि यह एक बग है, तो क्या किसी के पास कोई विचार है कि क्या मुझे एक वर्ग का समर्थन करने के लिए एक वर्ग का दो अलग-अलग प्रकार के एक सामान्य प्रकार का समर्थन करने के लिए कोई कामकाज हो सकता है इंटरफेस?

उत्तर

11

एक अंतरफलक के प्रकार के साथ as एक अंतरफलक डाली है, जो GUID इंटरफ़ेस खोजने के लिए उपयोग करता है का उपयोग करता है। एक GUID के साथ एक सामान्य इंटरफेस के लिए, प्रत्येक तत्कालता एक ही GUID हो जाता है। यदि एक ही प्रकार इंटरफ़ेस की कई प्रतियों को लागू करता है, तो GUID द्वारा देखे जाने वाले परिणामस्वरूप पहला इंटरफ़ेस वापस आ जाएगा।

कार्यक्रम काम करता है की उम्मीद के रूप में यदि आप एक इंटरफेस कलाकारों का उपयोग नहीं करते, और बदले इस तरह एक अंतरफलक रूपांतरण का उपयोग करें:

procedure Test; 
var 
    t : TTest<integer, string>; 
begin 
    t := TTest<integer, string>.Create(39, 'Blah'); 
    ShowMessage(ITest<string>(t).Val); 
    ShowMessage(IntToStr(ITest<Integer>(t).Val)); 
end; 

मूल रूप से, जब जेनरिक Win32 के लिए लागू किया जा रहा था, GUIDs पर अनुमति नहीं थी जेनेरिक इंटरफेस। हालांकि, जेनेरिक इंटरफेस के लिए गतिशील पूछताछ सामान्य कंटेनर परिदृश्यों के लिए वांछनीय था, और सामान्य रूप से, एक एल्गोरिदम के संदर्भ में टाइप-विशिष्ट सेवाओं के लिए सेवा प्रदाता से पूछताछ के लिए एक तंत्र के रूप में (जैसे सॉर्टिंग या सर्चिंग, जिसमें तुलनाकर्ताओं जैसी चीजों की आवश्यकता होती है और समानता परीक्षण)। तो एक नई योजना बनाई गई थी: जेनेरिक इंटरफ़ेस पर एक GUID है, लेकिन जेनेरिक इंस्टॉलेशन और फोल्ड (उदा। Xor) हैश के लिए GUI में प्रत्येक विशिष्ट और असंगत तत्कालता के लिए एक अद्वितीय GUID बनाने के लिए प्रकार तर्कों का हैश बनाएं। हालांकि, यह दिन में देर हो चुकी थी, और समय की बाधाओं के भीतर एक अच्छा कार्यान्वयन संभव नहीं था। लेकिन गतिशील पूछताछ की आवश्यकता बनी रही, इसलिए GUID रहे। यही कारण है कि वे आज के तरीके हैं।

अपने विशिष्ट परिदृश्य को हल करने के लिए, सबसे अच्छा मैं अनुशंसा कर सकता हूं कि स्पष्ट GUIDs के साथ अलग-अलग वंशजों का उपयोग करें; या इंटरफेस के लिए पूछताछ के लिए एक अलग तंत्र का उपयोग करें।

+0

हू। जानकार अच्छा लगा। धन्यवाद। आप जानकारी बैरी की सिर्फ एक सोने की खान हैं। समय देने के लिए धन्यवाद। – TrespassersW

+0

डी 2010 पहले से ही इस हैश, बैरी है? –

+0

दुर्भाग्यवश यह नहीं है। हालांकि मुझे वास्तव में इसमें देखना चाहिए। –

3

यह एक दिलचस्प समस्या है। ऐसा प्रतीत होता है कि संकलक हमेशा इंटरफ़ेस के अंतिम निर्दिष्ट संस्करण में इंटरफ़ेस का मानचित्रण कर रहा है (यदि आप ऑर्डर को स्वैप करते हैं तो यह दूसरी विधि को कॉल करता है)। यह इस तथ्य से हो सकता है कि दोनों इंटरफेस में एक ही GUID हस्ताक्षर है, इसलिए प्रेषक भ्रमित हो रहा है क्योंकि इंटरफ़ेस कॉल को देखते समय किस विधि को लागू किया जाना चाहिए।

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

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