2008-12-30 15 views
91

स्थिर सूचकांक सी # में क्यों अस्वीकृत हैं? मुझे कोई कारण नहीं दिखता कि उन्हें अनुमति क्यों नहीं दी जानी चाहिए और इसके अलावा वे बहुत उपयोगी हो सकते हैं।स्टेटिक इंडेक्सर्स?

उदाहरण के लिए:

static class ConfigurationManager { 

     public object this[string name]{ 
      get{ 
       return ConfigurationManager.getProperty(name); 
      } 
      set { 
       ConfigurationManager.editProperty(name, value); 
      } 
     } 

     /// <summary> 
     /// This will write the value to the property. Will overwrite if the property is already there 
     /// </summary> 
     /// <param name="name">Name of the property</param> 
     /// <param name="value">Value to be wrote (calls ToString)</param> 
     public static void editProperty(string name, object value) { 
      DataSet ds = new DataSet(); 
      FileStream configFile = new FileStream("./config.xml", FileMode.OpenOrCreate); 
      ds.ReadXml(configFile); 

      if (ds.Tables["config"] == null) { 
       ds.Tables.Add("config"); 
      } 

      DataTable config = ds.Tables["config"]; 

      if (config.Rows[0] == null) { 
       config.Rows.Add(config.NewRow()); 
      } 

      if (config.Columns[name] == null) { 
       config.Columns.Add(name); 
      } 

      config.Rows[0][name] = value.ToString(); 

      ds.WriteXml(configFile); 
      configFile.Close(); 
     } 

     public static void addProperty(string name, object value) { 
      ConfigurationManager.editProperty(name, value); 
     } 

     public static object getProperty(string name) { 
      DataSet ds = new DataSet(); 
      FileStream configFile = new FileStream("./config.xml", FileMode.OpenOrCreate); 
      ds.ReadXml(configFile); 
      configFile.Close(); 


      if (ds.Tables["config"] == null) { 
       return null; 
      } 

      DataTable config = ds.Tables["config"]; 

      if (config.Rows[0] == null) { 
       return null; 
      } 

      if (config.Columns[name] == null) { 
       return null; 
      } 

      return config.Rows[0][name]; 
     } 
    } 

ऊपर कोड बहुत एक स्थिर इंडेक्सर से लाभ होगा। हालांकि यह संकलित नहीं होगा क्योंकि स्थिर सूचकांक की अनुमति नहीं है। ऐसा क्यों है?

+0

अगला मैं स्थैतिक वर्ग पर प्रत्यक्ष आईनेमेरेबल कार्यान्वयन चाहता हूं, इसलिए मैं 'foreach (enum में var enum) कर सकता हूं :) :) – nawfal

उत्तर

55

अनुक्रमणिका अंकन संदर्भ की आवश्यकता होती this पर। चूंकि स्थैतिक विधियों में कक्षा के किसी विशेष उदाहरण का संदर्भ नहीं है, इसलिए आप उनके साथ this का उपयोग नहीं कर सकते हैं, और इसके परिणामस्वरूप आप स्थैतिक तरीकों पर सूचकांक नोटेशन का उपयोग नहीं कर सकते हैं।

आपकी समस्या का हल इस प्रकार एक सिंगलटन पद्धति का उपयोग कर रहा है:


    public class Utilities 
    { 
     static ConfigurationManager _configurationManager = new ConfigurationManager(); 
     public static ConfigurationManager ConfigurationManager 
     { 
      get 
      { 
       return _configurationManager; 
      } 
     } 
    } 

    public class ConfigurationManager 
    { 
     public object this[string value] 
     { 
      get 
      { 
       return new object(); 
      } 
      set 
      { 
       // set something 
      } 
     } 
    } 

अब आप Utilities.ConfigurationManager["someKey"] इंडेक्सर अंकन का उपयोग कॉल कर सकते हैं।

+90

लेकिन सूचकांक को 'इस' का उपयोग क्यों करना है? इसे मालफिस्ट की टिप्पणी के लिए उदाहरण डेटा – Malfist

+68

+1 तक पहुंचने की आवश्यकता नहीं है। सिर्फ इसलिए कि यह एक उदाहरण इंडेक्सर के लिए "यह" का उपयोग करता है इसका मतलब यह नहीं है कि वे अन्य वाक्यविन्यास के साथ नहीं आ सकते हैं। –

+30

सहमत हुए। आप सवाल पूछ रहे हैं। आपने मूल रूप से कहा है कि इसकी अनुमति नहीं है क्योंकि इसकी अनुमति नहीं है। -1 क्योंकि सवाल था "इसकी अनुमति क्यों नहीं है?" – xr280xr

5

एक के रूप में काम के आसपास है, तो आप एक उदाहरण इंडेक्सर एक सिंगलटन/स्थिर वस्तु पर परिभाषित कर सकते हैं (जैसे कि ConfigurationManager एक सिंगलटन, बजाय एक स्थिर वर्ग होने का है):

class ConfigurationManager 
{ 
    //private constructor 
    ConfigurationManager() {} 
    //singleton instance 
    public static ConfigurationManager singleton; 
    //indexer 
    object this[string name] { ... etc ... } 
} 
+0

आह, धन्यवाद, मैंने इसके बारे में सोचा नहीं था! – Malfist

76

मेरा मानना ​​है कि इसे बहुत उपयोगी नहीं माना जाता था। मुझे लगता है कि यह भी शर्म की बात है - एक उदाहरण जो मैं उपयोग करता हूं वह एन्कोडिंग है, जहां एन्कोडिंग। गेट एन्कोडिंग ("foo") एन्कोडिंग ["फू"] हो सकती है। मुझे नहीं लगता कि यह बहुत अक्सर आएगा, लेकिन किसी और चीज से अलग होने पर यह थोड़ा असंगत लगता है कि उपलब्ध न हो।

मुझे जांचना होगा, लेकिन संदिग्ध यह पहले से ही आईएल में उपलब्ध है।

+5

इंटरमीडिएट भाषा - .NET के लिए असेंबली भाषा का प्रकार। –

+10

क्या मुझे यहाँ लाया मुझे लगता है कि एक स्थिर संपत्ति के माध्यम से अपने आवेदन भर में इस्तेमाल समान मूल्यों का एक शब्दकोश को उजागर करता है एक कस्टम वर्ग है। मैं GlobalState.State [KeyName] से ग्लोबलस्टेट [KeyName] तक पहुंच को कम करने के लिए एक स्थिर सूचकांक का उपयोग करने की उम्मीद कर रहा था। अच्छा रहा होगा। – xr280xr

+1

Fwiw, 'ilasm में एक डिफ़ॉल्ट संपत्ति परिणाम शिकायत' टोकन 'static'' में सिंटेक्स त्रुटि पर एक संपत्ति और गेटर विधि के लिए आईएल में 'static' को instance' बदल रहा; मैं आईएल के मामलों में दखल देने में बहुत अच्छा नहीं हूं लेकिन यह कम से कम प्रारंभिक संख्या की तरह लगता है। – Amazingant

-2

यह कीवर्ड कक्षा के वर्तमान उदाहरण को संदर्भित करता है। स्टेटिक सदस्य फ़ंक्शंस में यह पॉइंटर नहीं है। इस कीवर्ड का उपयोग कन्स्ट्रक्टर, इंस्टेंस विधियों और इंस्टेंस एक्सेसर्स के भीतर से सदस्यों तक पहुंचने के लिए किया जा सकता है। (msdn से पुनर्प्राप्त)। चूंकि इस संदर्भ में वर्ग का एक उदाहरण स्थिर की प्रकृति के साथ संघर्ष करता है, क्योंकि स्थैतिक वर्ग के उदाहरण से जुड़ा नहीं है।

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

public class ConfigurationManager 
{ 
    public ConfigurationManager() 
    { 
     // TODO: Complete member initialization 
    } 
    public object this[string keyName] 
    { 
     get 
     { 
       return ConfigurationManagerItems[keyName]; 
     } 
     set 
     { 
       ConfigurationManagerItems[keyName] = value; 
     } 
    } 
    private static Dictionary<string, object> ConfigurationManagerItems = new Dictionary<string, object>();   
} 

यह आपको कक्षा के एक सदस्य तक पहुंचने की अनुमति देता है और बस इसका एक उदाहरण बना देता है और इसे अनुक्रमित करता है।

new ConfigurationManager()["ItemName"] 
+2

इसकी एक दिलचस्प वैकल्पिक हल है, लेकिन 1) यह परिचय दुष्प्रभाव (एक खाली उदाहरण वस्तु के निर्माण) जो स्मृति दबाव और कुछ वातावरण में विखंडन का कारण बन सकता, 2) 'से बर्बाद अतिरिक्त वर्ण नई()' इस्तेमाल किया जा सकता इसके बजाए सिंगलटन के क्वालीफायर नाम के लिए, जैसे 'क्यूरेंट' –

+1

जैसे [जूलियट का उत्तर] (http://stackoverflow.com/a/401275/1430156), यह सवाल का जवाब नहीं देता है कि स्थिर सूचकांक समर्थित क्यों नहीं हैं। सबसे पहले, प्रश्न "स्थिर सूचकांक" शब्द को "इस 'कीवर्ड का उपयोग करने वाले कुछ" तक सीमित नहीं करता है, और दूसरा,' यह 'सिंटैक्स' सार्वजनिक स्ट्रिंग में यह [int अनुक्रमणिका] 'सख्ती से उपयोग भी नहीं कर रहा है एक 'यह' सूचक (जैसा कि यह उदाहरण विधियों के शरीर में हो सकता है), लेकिन * टोकन * 'यह' का एक और उपयोग है।वाक्यविन्यास 'सार्वजनिक स्थैतिक स्ट्रिंग यह [int अनुक्रमणिका] 'थोड़ा * प्रतिबिंबित * हो सकता है, लेकिन यह अभी भी स्पष्ट नहीं होगा। –

+1

@ ओआरआरमैपर यह 'सार्वजनिक स्थैतिक स्ट्रिंग क्लास [int अनुक्रमणिका]' भी हो सकता है। –

-1

कारण यह है कि यह समझना मुश्किल है कि आप एक स्थिर सूचकांक के साथ वास्तव में क्या अनुक्रमणित कर रहे हैं।

आप कहते हैं कि कोड एक स्थिर सूचकांक से लाभ होगा, लेकिन क्या यह वास्तव में होगा?

ConfigurationManager.editProperty(name, value); 
... 
value = ConfigurationManager.getProperty(name) 
इस में

:: सभी यह करना होगा यह परिवर्तन है

ConfigurationManager[name] = value 
... 
value = ConfigurationManager[name] 

जो कोड किसी भी तरह से बेहतर नहीं है; यह कोड के कई लाइनों से छोटे नहीं है, यह स्वत: पूर्ण करने के लिए धन्यवाद लिखना आसान नहीं है और यह कम स्पष्ट है, के रूप में यह तथ्य यह है कि आप हो रही है और कुछ आप 'संपत्ति' कहते हैं सेट कर रहे हैं छुपाता है और यह वास्तव में करने के लिए पाठक बलों दस्तावेज़ पढ़ें जाना वास्तव में क्या इंडेक्सर रिटर्न या सेट, क्योंकि यह कोई तरीका नहीं है स्पष्ट है कि यह एक संपत्ति है कि आप के लिए का अनुक्रमण रहे हैं, जबकि दोनों के साथ में है:

ConfigurationManager.editProperty(name, value); 
... 
value = ConfigurationManager.getProperty(name) 

आप इसे जोर से और तुरंत पढ़ सकते हैं समझें कि कोड क्या करता है।

याद रखें कि हम कोड आसान (= तेजी से) को समझने के लिए कोड लिखने के लिए तेजी से होता है कि यह है कि, नहीं लिखना चाहते हैं। उस गति को गलती न करें जिस पर आप कोड को उस गति से दे सकते हैं जिस पर आप परियोजनाएं पूरी करते हैं।

+0

असहमत। यह केवल एक वैचारिक बिंदु है। और कोड मेरी राय में बेहतर दिखता है, हालांकि यह केवल मेरी राय है। – ouflak

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