2012-02-08 11 views
6

मुझे पता है कि शीर्षक बहुत व्यापक है - बहुत अधिक फैल रहा है!जेनिक्स, पॉलिमॉर्फिज्म, इंटरफेस: समाधान क्या है?

और मुझे आशा है कि यह प्रश्न विषयों पर एक बड़ी "जानकारी विकी चीज़" के लिए विकसित हो सकता है।

मैं क्या सीखा है - अब तक:

  • जेनेरिक्स का उपयोग करते समय - अवधारणाओं को समझने (covariance and contravariance)।
  • Do NOT "mis-use" विरासत के साथ संयुक्त जेनरिक की अवधारणा। मैंने किया और यह आपको सीधे covariance समस्याओं में सिर बना सकता है! सुनिश्चित करें कि आप जेनेरिक को अपने विरासत में सही बिंदु पर "तोड़ दें" - यदि आप दोनों को जोड़ रहे हैं।

(कृपया मुझे सही करें - अगर आपको लगता है कि मैं गलत हूं, गायब हूं या कुछ गलत समझा है)।

मेरे समस्या थी:

लेकिन अब से मैं अनगिनत घंटे खर्च करते हैं, यह पता लगाने की, इस "बड़ी पहेली" मैं मेरी मेज पर है हल करने के लिए कैसे की कोशिश कर रहा है। और मुझे आप में से कई उपयोगकर्ताओं के कुछ अच्छे जवाब मिल चुके हैं - लेकिन अब इसका समय बड़े पैमाने पर काम करने के लिए है।

मैं इस एक के साथ जेनेरिक्स में कदम: Generics and Polymorphism working together

और अब मैं थोड़े पर अटक कर रहा हूँ यह एक: Situations where Generics won't work

मैं क्यों सहप्रसरण समस्याओं के साथ खत्म - में मेरी कक्षा प्रक्रिया की वजह से है मेरा पदानुक्रम

तो मुझे आश्चर्य है कि इंटरफेस इस "गाथा" में मेरा अगला साहसिक कदम है या नहीं। एक कॉन्वर्सिस समस्या "एक कदम" कैसे करें। एक बात यह जानना है कि आपको वास्तव में यह समस्या है - एक और बात यह है कि "इसके आसपास कैसे काम करना है"।

तो यदि आप में से कोई भी अच्छा लोग "वहां से बाहर" इस ​​पर कोई राय है - मैं सभी कान हूं। असल में: मुझे इंटरफ़ेस के लिए जाने के लिए कहें (मैंने कभी खुद को खरोंच से नहीं किया है)। या .. मुझे उस दिशा में एक हड्डी फेंक दें जो आप सुझाएंगे।

मेरा वर्तमान स्रोत पूल शीर्ष लिंक से दूसरे लिंक में बताया गया है।

यहां मेरे पिछले post से एक छोटा स्निपेट है जो मेरी कॉन्वर्सिस समस्या दिखाता है। David कृपया समझाया - मैं झाड़ी में क्यों भाग गया .. लेकिन अब मुझे जानकारी चाहिए - इसके चारों ओर कैसे दौड़ें।

var  
    aList : TBaseList<TBaseObject>; // used as a list parameter for methods 
    aPersonList : TPersonList<TPerson>; 
    aCustomerList : TCustomerList<TCustomer>; 
begin 
    aPersonList := TPersonList<TPerson>.Create; 
    aCustomerList := TCustomerList<TCustomer>.Create; 

    aList := aCustomerList; <-- this FAILS !! types not equal .. 

end; 

सादर

+1

अगर हम वास्तव में जानते हैं कि आपकी वास्तविक समस्या क्या है तो इससे मदद मिलेगी। मेरे अनुभव में, कॉन्वर्सिस शायद ही कभी एक समस्या है, अगर डिजाइन बहुत जटिल नहीं है। IOW, हमें असली समस्या बताएं, इसलिए हमारे पास हल करने के लिए कुछ ठोस है। –

+0

@RudyVelthuis अच्छी तरह से ... जैसा कि आप उल्लेख करते हैं - यह बहुत जटिल है और पूर्व [पोस्ट] (http://stackoverflow.com/q/9140485/696574) से बहुत सी पुनर्लेखन की आवश्यकता होगी। लेकिन मूल रूप से यह वही समस्या है - केवल सवाल बदल गया है। चूंकि अब मैं जानता हूं कि मैंने क्या गलत किया है - मुझे उम्मीद है कि कोई मुझे समाधान की दिशा में इंगित कर सकता है। यदि यह अभी भी अस्पष्ट है - मुझे बताएं और मैं जितना अच्छा कर सकता हूं उतना अच्छा प्रयास करूँगा। –

+0

समस्या के आसपास काम करने के लिए कैसे समस्या * है * पर निर्भर करता है। एक बार जब आप 'एलीस्ट' को मान देते हैं, तो आप उस चर के साथ * क्या करने की अपेक्षा करते थे? (इसके अलावा, टीपीर्सलिस्ट और टीसी कस्टमर लिस्ट जेनेरिक क्यों हैं? * * * क्या आपके पास टीपीर्सनलिस्ट है?) –

उत्तर

5

आप जो भी करना चाहते हैं वह नहीं कर सकते हैं, लेकिन ऐसा नहीं है कि आप जेनेरिक का उपयोग कैसे करते हैं। रॉब केनेडी ने कहा, यह TCustomerList<TCustomer> और TPersonList<TPerson> होने का कोई मतलब नहीं है। जेनेरिक की सुंदरता यह है कि आप विभिन्न तत्व प्रकारों के लिए एक ही सूची का उपयोग कर सकते हैं। इसका मतलब है कि सूची और तत्व प्रकार में कोई निर्भरता नहीं होनी चाहिए।

कुछ की तरह आप कर सकते हैं:

procedure TSomething.ProcessList<T: TBaseObject>(const aList: TBaseList<T>); 
begin 
    // process the list using code that is independent of the actual type of T. 
end; 

... 

var 
    aCustomerList: TBaseList<TCustomer>; 
    aPersonList: TBaseList<TPerson>; 
begin 
    ProcessList(aCustomerList); 
    ProcessList(aPersonList); 

शायद आप जेनरिक संभाल नहीं किया प्रकार निष्कर्ष की T (कुछ प्रारंभिक संस्करणों निर्दिष्ट करने के लिए हो सकता है - यानी कि वह के प्रकार से T के प्रकार inferes पैरामीटर - बहुत अच्छी तरह से), यानी

ProcessList<TCustomer>(aCustomerList); 
    ProcessList<TPerson>(aPersonList); 

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

इंटरफेस इस समस्या से आपको बिल्कुल मदद नहीं करेगा। आप वर्गों को कुछ क्षमताओं, यानी सूचियों के तत्वों को इंटरफेस (अन्य प्रकार के बहुरूपता) के माध्यम से दे सकते हैं। लेकिन वह covariance संभाल नहीं होगा।

+0

+1 टाइप अनुमान का अर्थ है कि आपको इसे 'प्रोसेसलिस्ट (ए-कस्टमरलिस्ट)' और 'प्रोसेसलिस्ट (एपर्सलिस्ट)' के रूप में लिखने में सक्षम होना चाहिए। –

+0

@ डेविड: मुझे पता है, लेकिन टाइप अनुमान अनुमानित रूप से अपेक्षित काम नहीं करता है, खासकर जेनरिक्स का समर्थन करने वाले पुराने संस्करणों में नहीं। ध्यान दें कि मैंने प्रोसेसलिस्ट (आदि) लिखा था, लेकिन यह साबित कर दिया कि इसे इस तरह से स्वीकार नहीं किया जा सकता है। –

+0

"शायद आपको निर्दिष्ट करना पड़ सकता है" थोड़ा अस्पष्ट है। मुझे लगता है कि यह मुझे उलझन में है। आप बाहर आने से बेहतर हो सकते हैं और कह सकते हैं कि संक्षिप्त वाक्यविन्यास काम करना चाहिए, लेकिन संकलक के कुछ संस्करण इसे पसंद नहीं करते हैं।उत्सुकता से मैंने हाल ही में एक जेनेरिक बग QC'd किया जो कि दूसरी तरफ था। प्रकार अनुमान वाक्यविन्यास काम किया, वैकल्पिक आंतरिक त्रुटि उत्पन्न किया। –

0

मैं के लिए जाना होगा:

TCustomCustomerList = class(TBaseList<TBaseObject>) 
end; 

TCustomerList = class(TCustomCustomerList) 
end; 

किया जाए या नहीं इस स्वीकार्य है में अपने डिजाइन पूरी तरह से एक अलग बात है। यदि आप जिस लक्ष्य को हासिल करने का प्रयास कर रहे हैं वह TCustomerList को TBaseList चर में असाइन करना है, तो यह जाने का तरीका होगा।

+0

तो आप प्रस्ताव दे रहे हैं कि मुझे आधार परिभाषा के ऊपर जेनेरिक श्रृंखला तोड़नी चाहिए ... हमम ... मेरे पास एक परीक्षण परियोजना में एक दरार होगी और आपको वापस मिल जाएगी। इससे पहले कि मैं आपसे वापस आ सकूं, कुछ घंटों लग सकते हैं। –

+0

जैसा कि आप देख सकते हैं कि मैं वर्तमान में परीक्षण कर रहा हूं ... और अब तक ऐसा लगता है कि मैं रुडी से सलाह के साथ जाऊंगा (मूल रूप से आपके जैसा ही - लेकिन अधिक विस्तार से समझाया गया है)। –

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