2010-12-08 9 views
5

मेरा मानना ​​है कि यह बहुत बेवकूफ है, और मैं एक सा सवाल इस तरह का पूछने के लिए शर्मिंदा हूँ, लेकिन मैं अभी भी इस सवाल का जवाब नहीं मिल सका:कैसे सूची <T> जोड़ें (ऑब्जेक्ट वैल्यू) लागू नहीं करता है?

मैं कक्षा List<T>, जो IList implemetns पर देख रहा हूँ।

public class List<T> : IList 

तरीकों IList में शामिल में से एक

int Add(object value) 

मैं समझता हूँ कि List<T> कि विधि (प्रकार सुरक्षा ...) जोखिम नहीं होगा है, और यह वास्तव में नहीं है। लेकिन यह कैसे हो सकता है? कक्षा को पूरे इंटरफेस को लागू नहीं करना चाहिए?

+0

मुझे यकीन नहीं है कि इसका खुलासा करके आपका क्या मतलब है, इंटरफेस में केवल सार्वजनिक सदस्य ही हो सकते हैं। –

+0

@ ब्रैड: 'सूची ' एक इंटरफ़ेस नहीं है, और वह कह रहा है कि 'सूची ' का खुलासा नहीं करना चाहिए। –

+0

इसे "स्पष्ट अंतरफलक कार्यान्वयन" कहा जाता है। – codymanix

उत्तर

10

मुझे विश्वास है कि यह (इंटरफेस) विधि implemented explicitly है:

public class List<T> : IList 
{ 
    int IList.Add(object value) {this.Add((T)value);} 
} 

ऐसा करके, Add(object) प्रक्रिया गुप्त रखी करके होगा। यदि आप List<T> इंस्टेंस को IList उदाहरण पर वापस डालते हैं, तो आप इसे केवल कॉल करने में सक्षम होंगे।

+0

आप स्पष्ट कार्यान्वयन के बारे में सही हैं। लेकिन आपको अपना उदाहरण ठीक करना चाहिए ("रिकर्सन" और "संकलित नहीं कर सकता" मेरे दिमाग में पॉप-अप रखना जारी रखें) ... :) – rsenna

+0

आपको काम करने के लिए टी को मूल्य डालना होगा। – Sean

2

List<T> स्पष्ट रूप से IList.Add(object value) लागू करता है, यही कारण है कि यह आमतौर पर दिखाई नहीं देता है। ताकि आप IList इसका इस्तेमाल करने के पहले कास्ट करना है

IList list = new List<string>(); 
list.Add(new SqlDataReader()); // valid at compile time, will fail at runtime 
1

यह यह स्पष्ट रूप से लागू करता है,: आप निम्न कार्य करके परीक्षण कर सकते हैं।

List<int> l = new List<int>(); 
IList il = (IList)l; 
il.Add(something); 
1

आप कॉल कर सकते हैं यह इंटरफ़ेस करने के लिए अपनी सूची उदाहरण कास्टिंग जा पहला:

List<int> lst = new List<int>(); 
((IList)lst).Add("banana"); 

और आप के रूप में अच्छा, क्रम मिलेगा, ArgumentException।

2

परावर्तक के लिए एक त्वरित यात्रा पता चलता है कि IList.Add इस तरह कार्यान्वित किया जाता है:

int IList.Add(object item) 
{ 
    ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item); 
    try 
    { 
     this.Add((T) item); 
    } 
    catch (InvalidCastException) 
    { 
     ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T)); 
    } 
    return (this.Count - 1); 
} 

दूसरे शब्दों में, कार्यान्वयन करने के लिए इसे डाले टी यह काम करने के लिए और इसे आप एक गैर पारित विफल रहता है टी में संगत प्रकार।

+0

जानकारी सही है, लेकिन यह सवाल का जवाब नहीं देती है। – Guffa

+0

यकीन है कि यह करता है। IList.Add एक कलाकार करता है और IList कहते हैं। कार्यान्वयन जोड़ें। – Sean

1

Frederik is right कि List<T> के IList के कार्यान्वयन कुछ सदस्यों, विशेष रूप से उन है कि एक खतरा सुरक्षा टाइप करने के लिए स्पष्ट है।

वह अपने उत्तर में जो कार्यान्वयन सुझाता है वह सही नहीं हो सकता है, क्योंकि यह संकलित नहीं होगा।

इस तरह के मामलों में, सामान्य दृष्टिकोण पर एक बहादुर प्रयास करना है, को इंटरफ़ेस सदस्य को काम करने के लिए प्रयास करें, लेकिन अगर यह असंभव है तो छोड़ दें।

ध्यान दें कि IList.Add विधि वापस जाने के लिए परिभाषित किया गया है:

स्थिति है जिसमें नई तत्व सम्मिलित किया गया था, या -1 लिए संकेत मिलता है कि आइटम संग्रह में सम्मिलित नहीं किया किया गया था।

तो वास्तव में, एक पूर्ण कार्यान्वयन संभव है:

int IList.Add(object value) 
{ 
    if (value is T) 
    { 
     Add((T)value); 
     return Count - 1; 
    } 

    return -1; 
} 

यह निश्चित रूप से, एक अनुमान सिर्फ है। (यदि आप वास्तव में निश्चित रूप से जानना चाहते हैं, तो आप हमेशा Reflector का उपयोग कर सकते हैं।) यह थोड़ा अलग हो सकता है; उदाहरण के लिए यह NotSupportedException फेंक सकता है, जिसे ReadOnlyCollection<T> के IList<T> के कार्यान्वयन जैसे अपूर्ण इंटरफ़ेस कार्यान्वयन के लिए अक्सर किया जाता है। लेकिन चूंकि उपरोक्त IList.Add की दस्तावेजी आवश्यकताओं को पूरा करता है, मुझे संदेह है कि यह वास्तविक चीज़ के करीब है।

+1

यदि आप गलत प्रकार के आइटम को जोड़ने का प्रयास करते हैं तो वास्तविक कार्यान्वयन (कम से कम .NET4 में) 'ArgumentException' फेंकता है)। (और, अगर मैं सही ढंग से याद करता हूं, तो .NET4 से पहले एक छोटी सी बग थी, जहां 'सूची > '' IList.Add' के माध्यम से' शून्य 'जोड़ने की कोशिश कर रहा है, अपवाद को गलत तरीके से फेंक देगा।) – LukeH

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