2010-01-06 12 views
11

कुछ कोड पढ़ने करना और इस स्निपेट कि मैंने नहीं देखा है से पहले पर ठोकर खाई:सी # सूचकांक का बिंदु या लाभ क्या है?

public SomeClass { 
    public someInterface this[String strParameter] { 
    get { 
     return SomeInternalMethod(strParameter); 
    } 
    } 
} 

ऐसा लगता है कि यह इस प्रकार कहा जाता है:

SomeClass _someClass = new SomeClass(); 
SomeInterface returnedValue = _someClass["someString"]; 

मैं जहां इस समारोह होगा में दिलचस्पी है उपयुक्त हो या इस शैली में लिखने का इरादा क्या हो। उदाहरण के लिए फ़ंक्शन को कॉल करने पर इसे क्यों पसंद किया जाएगा?

+1

यह प्राकृतिक, सुरुचिपूर्ण है, आंख को प्रसन्न करता है, समझ को बढ़ाता है। विधि कॉल उबाऊ हैं। इसे देखें: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html –

उत्तर

19

भाषा विनिर्देश, खंड 10.9, जिसमें कहा गया है देखें।

Indexers और गुण निम्न तरीकों से अवधारणा में बहुत समान हैं, लेकिन अलग-अलग:

  • एक संपत्ति, इसका नाम से पहचाना जाता है, जबकि एक इंडेक्सर उसके हस्ताक्षर से पहचाना जाता है।
  • एक संपत्ति को सरल नाम (§7.5) के माध्यम से एक्सेस किया जाता है।2) या सदस्य-पहुंच (§7.5.4), जबकि एक इंडेक्सर तत्व को तत्व-पहुंच (§7.5.6.2) के माध्यम से एक्सेस किया जाता है।
  • एक संपत्ति एक स्थिर सदस्य हो सकती है, जबकि एक सूचक हमेशा एक उदाहरण सदस्य होता है।
  • किसी प्रॉपर्टी का एक्सेसर किसी पैरामीटर वाले विधि से मेल खाता है, जबकि इंडेक्सर का एक्सेस प्राप्तकर्ता इंडेक्सर के समान औपचारिक पैरामीटर सूची के साथ एक विधि से मेल खाता है।
  • किसी संपत्ति का एक सेट एक्सेसर एक विधि के अनुरूप एक पैरामीटर के साथ मेल खाता है, जबकि इंडेक्सर का एक सेट एक्सेसर इंडेक्सर के समान औपचारिक पैरामीटर सूची के साथ एक विधि के अनुरूप होता है, साथ ही मूल्य का एक अतिरिक्त पैरामीटर भी होता है।
  • यह इंडेक्सर एक्सेसर के लिए एक इंडेक्सर पैरामीटर के समान नाम के साथ एक स्थानीय चर घोषित करने के लिए एक संकलन-समय त्रुटि है।
  • ओवरराइडिंग संपत्ति घोषणा में, विरासत संपत्ति को सिंटैक्स बेस.पी का उपयोग करके एक्सेस किया जाता है, जहां पी संपत्ति का नाम है। ओवरराइडिंग इंडेक्सर घोषणा में, विरासत सूचकांक को सिंटैक्स बेस [ई] का उपयोग करके एक्सेस किया जाता है, जहां ई अभिव्यक्तियों की अल्पविराम से अलग सूची है।

    var myList = new List<string>(); 
    myList.Add("One"); 
    myList.Add("Two"); 
    myList.Add("Three"); 
    
    for(int i = 0; i < myList.Count; i++) { 
        string s = myList[i]; 
    } 
    

    इंडेक्सर एक वस्तु है कि एक संग्रह को लागू करता है की "प्राथमिक कुंजी" है:

+2

मुझे पता है कि मुझे इसे हाइजैक नहीं करना चाहिए, लेकिन शायद आप ब्लॉग कर सकते हैं कि क्यों नहीं हैं स्टेटिक इंडेक्सर्स? मैं चौंक गया जब मैंने देखा कि वे अस्तित्व में नहीं हैं, सिर्फ इसलिए कि यह इतना अच्छा, शॉर्टेंड तरीका है। (इससे पहले जॉन ने अच्छा एन्कोडिंग ["यूटीएफ 8"] उदाहरण लाया है :)) –

+3

मैंने अभी डिज़ाइन नोट्स आर्काइव की जांच की है और स्थिर इंडेक्सर्स के निर्णय को न्यायसंगत बनाने में कुछ भी नहीं है। इसलिए मुझे अपने सामान्य स्पष्टीकरण पर वापस आना चाहिए कि हमारे पास कोई सुविधा क्यों नहीं है: कोई भी नहीं सोचा कि यह वास्तविक बनाने के लिए पैसे खर्च करने का एक अच्छा विचार था। मुझे कल्पना है कि यह वही स्पष्टीकरण यह भी बताता है कि सूचकांक सामान्य क्यों नहीं हो सकते हैं। –

+0

कूल :) "डिफ़ॉल्ट" स्पष्टीकरण के बारे में अच्छी बात यह है कि यह संभवतः कभी भी संभव होने का दरवाजा बंद नहीं करता है। मुझे नहीं पता कि यह सुविधा कितनी "भारी" है (और मैं यह कहकर खुद को अयोग्य नहीं ठहराऊंगा "लेकिन यह केवल इतना छोटा बदलाव है!" यह जानने के बिना कि कंपाइलर और सीएलआर वास्तव में कैसे काम करते हैं), लेकिन यह बेहतर नहीं है "हमने नहीं किया यह एक्स, वाई और जेड की वजह से इसे कार्यान्वित करना असंभव बनाता है "। –

5

कई मामलों में, 'इंडेक्स' वाक्यविन्यास बहुत समझ में आता है। यह विशेष रूप से उपयोगी होता है अगर कुछ क्लास कुछ प्रकार के संग्रह का प्रतिनिधित्व करता है।

3

यह आपको अपने प्रश्न में उल्लेखित सहयोगी सरणी लुकअप (ए.के.ए. "शब्दकोश शैली") करने की अनुमति देता है।

और यह पूरा बिंदु है। इस तरह के कुछ लोग, विशेष रूप से लोग जो पाइथन या PHP

0

पर इंडेक्स ऑपरेटर [ ] का कार्यान्वयन करते हैं।

0

यह एक ऑपरेटर ओवरलोड है। उपयोगी है अगर आप एक संग्रह वर्ग लिख रहे हैं उदाहरण के लिए जहां इसे सरणी नोटेशन का उपयोग करके इसे एक्सेस करना समझदारी होगी, उदा। संग्रह [someIndex]।

आप निश्चित रूप से एक संग्रह लिख सकते हैं। गेटमेंट (कुछ इंडेक्स) फ़ंक्शन समतुल्य है, लेकिन यह एक शैली/पठनीयता की बात है।

3

"इस" कीवर्ड एक इंडेक्सर से http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

कि "Indexers कक्षा या struct के उदाहरण सिर्फ सरणियों की तरह अनुक्रमित करने के लिए। Indexers सिवाय इसके कि उनके accessors पैरामीटर पर ध्यान गुण जैसे लगते हैं अनुमति देते हैं।"

+0

आपका क्या मतलब है: "यह" कीवर्ड एक सूचकांक है? – spender

0

ठीक है आप इस विधि का उपयोग एक कुंजी-मूल्य जोड़ी वर्ग में कर सकते हैं।

मुझे यकीन नहीं है कि समसामयिक वर्ग सी # में क्या है, लेकिन सी ++ एसटीएल में, नक्शा वर्ग है जहां आप SomeObject["key"] के साथ विधि को कॉल करते हैं और यह उस कुंजी से जुड़े "मान" को वापस कर देगा।

+0

सी # में समान वर्ग System.Collections.Generic.Dictionary (शब्दकोश को छोड़कर हैश लुकअप का उपयोग करता है, जबकि नक्शा कुंजी को ऑर्डर करता है) –

0

इसे एक इंडेक्सर कहा जाता है, तो वे आपको सूची <>, ऐरेलिस्ट, शब्दकोश <> और सरणी वाक्यविन्यास का उपयोग करके अन्य सभी संग्रहों का उपयोग करने की अनुमति देते हैं।

यह सिर्फ वाक्य रचनात्मक चीनी है, लेकिन सही उपयोग किए जाने पर यह कुछ पठनीयता देता है।

एक Indexer एक सदस्य है कि एक वस्तु एक सरणी के रूप में एक ही तरह से अनुक्रमित करने के लिए सक्षम बनाता है:

1

आप हो सकता है पहले से ही कुछ इसी तरह से पहले भर में ठोकर खाई। यह एक समारोह लिखने के लिए सिर्फ एक शॉर्टेंड तरीका है जैसे GetValue (अनुक्रमणिका) - सिंटेक्टिक चीनी, यदि आप चाहते हैं। लेकिन यह इरादा स्पष्ट भी बनाता है।

13

ऐसा लगता है कि बहुत सारे उत्तर इंडेक्सर पर ध्यान केंद्रित कर रहे हैं, न कि आप एक का उपयोग क्यों करना चाहते हैं।

जहां तक ​​मेरा सवाल है, यहां प्रेरणा एक इंडेक्सर उपयोग करने के लिए है:

आप एक वर्ग किसी प्रकार का संग्रह है उस पर काम कर रहे हैं, लेकिन आप वर्ग उपयोगकर्ताओं के लिए प्रकट करना चाहते हैं (कक्षा के उपभोक्ता) जैसे कि यह एक संग्रह है।

एडीओ.NET में DataRow कक्षा का सबसे अच्छा उदाहरण मैं सोच सकता हूं। यदि आप DataRow के पांचवें सेल का मान प्राप्त करना चाहते हैं, तो आप या तो DataRow.Item[4] या DataRow[4] का उपयोग कर सकते हैं। उत्तरार्द्ध रूप एक सुविधाजनक और तार्किक शॉर्टकट है, और यह बहुत अच्छी तरह से दिखाता है कि आप एक सूचकांक का उपयोग क्यों करना चाहते हैं। उपयोगकर्ता के लिए, DataRow को केवल कोशिकाओं का संग्रह माना जा सकता है (भले ही यह वास्तव में उससे अधिक हो), इसलिए यह समझने के लिए कि सेल मूल्यों को सीधे प्राप्त करने और सेट करने में सक्षम होना समझ में आता है, यह याद रखने के बिना कि आप वास्तव में हैं Item प्राप्त/स्थापित करना।

उम्मीद है कि मदद करता है।

0

मेरी राय में, यह सिर्फ एक वाक्यविन्यास सुविधा है। कहाँ नहीं यह प्रयोग करेंगे:

public SomeClass { 
    private int[] nums; 
    public GetVal this[int ind] { 
    get { 
     return nums[ind]; // this is pointless since array is already indexed 
    } 
    } 
} 

कहाँ इसे से को फायदा होगा:

public Matrix { 
    private Dictionary<string, double> matrixData; // Matrix indecies, value 
    public double this[int row, int col] { 
    get { 
     return matrixData[string.Format("{0},{1}", row, col)]; 
    } 
    } 
} 

आप देख सकते हैं, किसी कारण से, अपने डेटा एक शब्दकोश एक साथ अनुक्रमित है स्ट्रिंग कुंजी और आप इसे दो पूर्णांक indecies के साथ कॉल करना चाहते हैं और अभी भी अपना डेटा प्रकार बदलना नहीं चाहते हैं:

Matrix m = new Matrix(); 
... 
Console.WriteLine(m[1,2]); 
संबंधित मुद्दे