স্ট্যাটিক ইনডেক্সার?


119

স্থির সূচকগুলিকে কেন সি # তে অনুমোদিত নয়? তাদের অনুমতি না দেওয়ার কোনও কারণ আমি দেখতে পাচ্ছি এবং তদ্ব্যতীত তারা খুব কার্যকর হতে পারে।

উদাহরণ স্বরূপ:

public static class ConfigurationManager 
{
        public object this[string name]
        {
            get => 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) 
        {
            var ds = new DataSet();
            var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
            ds.ReadXml(configFile);

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

            var 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) 
        {
            var ds = new DataSet();
            var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
            ds.ReadXml(configFile);
            configFile.Close();

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

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

            if (config.Rows[0] == null) return null;
            if (config.Columns[name] == null) return null;

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

উপরের কোডটি একটি স্ট্যাটিক ইনডেক্সার দ্বারা প্রচুর উপকার পাবেন। তবে এটি সংকলন করবে না কারণ স্থির সূচকের অনুমতি নেই। কেন এমন হয়?


পরবর্তী আমি স্ট্যাটিক ক্লাসে সরাসরি আইনিংরেবল বাস্তবায়ন চাই, তাই আমিও করতে পারি foreach (var enum in Enum):)
নওফাল

উত্তর:


72

সূচক স্বরলিপিটির জন্য একটি রেফারেন্স প্রয়োজন this। স্ট্যাটিক পদ্ধতিতে ক্লাসের কোনও নির্দিষ্ট উদাহরণের রেফারেন্স না thisথাকায় আপনি সেগুলি ব্যবহার করতে পারবেন না এবং ফলস্বরূপ আপনি স্থির পদ্ধতিতে সূচীকরণ চিহ্ন ব্যবহার করতে পারবেন না।

আপনার সমস্যার সমাধানটি নীচে সিঙ্গেলটন প্যাটার্নটি ব্যবহার করছে:

public class Utilities
{
    private static ConfigurationManager _configurationManager = new ConfigurationManager();
    public static ConfigurationManager ConfigurationManager => _configurationManager;
}

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

এখন আপনি Utilities.ConfigurationManager["someKey"]সূচক স্বরলিপি ব্যবহার করে কল করতে পারেন ।


110
তবে সূচককে 'এটি' ব্যবহার করতে হবে কেন? এটি উদাহরণস্বরূপ ডেটা অ্যাক্সেস করতে হবে না
ম্যালফিস্ট

80
মালফিস্টের মন্তব্যের জন্য +1। কেবলমাত্র উদাহরণস্বরূপ সূচকটির জন্য "এটি" ব্যবহার করার অর্থ এই নয় যে তারা অন্যান্য বাক্য গঠন নিয়ে আসতে পারেনি।
জন স্কিটি

40
একমত। আপনি ভিক্ষা করছেন। আপনি মূলত বলেছিলেন যে এটি অনুমোদিত নয় কারণ কারণ এটি অনুমোদিত নয়। -1 কারণ প্রশ্নটি ছিল "কেন এটি অনুমোদিত নয়?"
xr280xr

15
@ xr280xr +1 "প্রশ্নটি ভিক্ষা" এর সঠিক ব্যবহারের জন্য :) :) আমারও একই অভিযোগ রয়েছে।
রেডফিল্টার

14
-1 কারণ এই উত্তরটি ধরে নিয়েছে যে কোনও স্ট্যাটিক ইনডেক্সার প্রয়োগ করা হলে বর্তমান নোটেশনটিই কেবলমাত্র সম্ভাব্য স্বরলিপি। thisকোনও সূচকের ব্যবহারের প্রয়োজন হয় না, এটি সম্ভবত অন্যান্য কীওয়ার্ডের থেকেও বেছে নেওয়া হয়েছিল কারণ এটি সবচেয়ে বেশি অর্থবোধ করেছিল। একটি স্ট্যাটিক বাস্তবায়ন, নিম্নলিখিত সিনট্যাক্স বেশ টেকসই হতে পারে: public object static[string value]thisস্থির প্রসঙ্গে কিওয়ার্ডটি ব্যবহার করার দরকার নেই ।
আইনস্টাইনসি 26'15

91

আমি বিশ্বাস করি এটি মারাত্মকভাবে কার্যকর হিসাবে বিবেচিত হবে না। আমি মনে করি এটি খুব লজ্জাজনক - আমি যে উদাহরণটি ব্যবহার করতে চাই তা হ'ল এনকোডিং, যেখানে Encoding.GetEncoding("foo")হতে পারে Encoding["Foo"]। আমি মনে করি না এটি খুব ঘন ঘন উঠে আসবে , তবে অন্য কিছু বাদ দিয়ে এটি উপলব্ধ না হওয়ার জন্য কিছুটা অসঙ্গতি অনুভব করে।

আমাকে যাচাই করতে হবে, তবে আমি সন্দেহ করি এটি ইতিমধ্যে আইএল (অন্তর্বর্তী ভাষা) এ উপলব্ধ।


6
মধ্যবর্তী ভাষা -। নেট জন্য সমাবেশ ভাষা সাজানোর।
জন স্কিটি

14
যা আমাকে এখানে এনেছে তা হ'ল আমার একটি কাস্টম ক্লাস রয়েছে যা আমার অ্যাপ্লিকেশন জুড়ে ব্যবহার করা সাধারণ মানগুলির একটি অভিধান একটি স্ট্যাটিক সম্পত্তির মাধ্যমে প্রকাশ করে। আমি গ্লোবালস্টেট.স্টেট [কীনাম] থেকে কেবল গ্লোবাল স্টেট [কীনাম] এ অ্যাক্সেস ছোট করার জন্য একটি স্ট্যাটিক ইনডেক্সার ব্যবহার করার আশা করছিলাম। ভাল লাগত।
xr280xr

1
FWIW পরিবর্তন instanceকরতে staticilasm অভিযোগ একটি ডিফল্ট সম্পত্তি ফলাফলের সম্পত্তি এবং সংগ্রহকারী পদ্ধতির জন্য বিশ্বের সেরা syntax error at token 'static'; আমি আইএল সম্পর্কিত বিষয়গুলিতে مداخلت করতে পারছি না তবে এটি কমপক্ষে একটি প্রাথমিক নম্বর বলে মনে হচ্ছে।
আশ্চর্যজনক

8

ওয়ার্ক-এওয়ার্ড হিসাবে, আপনি একটি সিঙ্গলটন / স্ট্যাটিক অবজেক্টে ইনস্ট্যান্স ইনডেক্সারটি সংজ্ঞায়িত করতে পারেন (বলুন যে কনফিগারেশন ম্যানেজারটি স্ট্যাটিক ক্লাস হওয়ার পরিবর্তে সিঙ্গলটন):

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

1

বৈশিষ্ট্যগুলি সংরক্ষণ করার জন্য আমি একটি স্ট্যাটিক ইনডেক্সারের প্রয়োজন (ভাল, আরও ভাল-এর মতো )ও ছিলাম, তাই আমি কিছুটা বিশ্রী কাজটি আবিষ্কার করেছি:

শ্রেণীর মধ্যে আপনি একটি স্ট্যাটিক ইনডেক্সার রাখতে চান (এখানে: উপাদান), একই নামের একটি উপক্লাস তৈরি করুন "ডিক্ট"। উক্ত সাবক্লাসের উদাহরণ হিসাবে এটি একটি পঠনযোগ্য স্ট্যাটিক দিন এবং তারপরে আপনার পছন্দসই সূচক যুক্ত করুন।

সর্বশেষে, ক্ল্যাটিকটিকে স্ট্যাটিক আমদানি হিসাবে যুক্ত করুন (অতএব কেবলমাত্র স্থির ক্ষেত্রটি প্রকাশ করার জন্য সাবক্লাস)।

import static Element.ElementDict;

public class Element {
    // .... 
    private static readonly Dictionary<string, object> elemDict = new Dictionary<string, object>();
    public class ElementDict {
        public readonly static ElementDict element = new ElementDict();
        public object this[string key] {
            get => elemDict.TryGetValue(key, out object o) ? o : null;
            set => elemDict[key] = value;
        }
    }
}

এবং তারপরে আপনি এটিকে টাইপ হিসাবে, বা অভিধান ছাড়া মূলধনটি ব্যবহার করতে পারেন:

var cnt = element["counter"] as int;
element["counter"] = cnt;

তবে হায়, যদি কেউ আসলে "মান"-টাইপ হিসাবে বস্তুটি ব্যবহার করে, তবে নীচেরটি এখনও আরও সংক্ষিপ্ত হবে (কমপক্ষে ঘোষণা হিসাবে) এবং তাত্ক্ষণিক টাইপকাস্টিং সরবরাহ করবে:

public static T load<T>(string key) => elemDict.TryGetValue(key, out object o) ? (T) o : default(T);
public static void store<T>(string key, T value) => elemDict[key] = value;

var cnt = Element.load<int>("counter");
Element.store("counter", cnt);

0

সি # 6 এ নতুন নতুন নির্মাণগুলির সাথে, আপনি কোনও সম্পত্তি প্রকাশের বডি দিয়ে সিঙ্গলটন প্যাটার্নটিকে সহজতর করতে পারেন। উদাহরণস্বরূপ, আমি নিম্নলিখিত শর্টকাটটি ব্যবহার করেছি যা কোড-লেন্সের সাথে দুর্দান্তভাবে কাজ করে:

public static class Config
{
   public static NameValueCollection Get => ConfigurationManager.AppSettings;
}

পুরানো কোড আপগ্রেড করার জন্য এবং আপনার অ্যাপ্লিকেশন সেটিংস অ্যাক্সেসকে একীকরণের জন্য এটি সন্ধান-প্রতিস্থাপন-সক্ষম হওয়ার অতিরিক্ত সুবিধা রয়েছে।


-2

এই কীওয়ার্ডটি ক্লাসের বর্তমান উদাহরণকে বোঝায়। স্থির সদস্য ক্রিয়াকলাপগুলির মধ্যে এই পয়েন্টারটি নেই। এই কীওয়ার্ডটি কনস্ট্রাক্টর, উদাহরণ পদ্ধতি এবং উদাহরণ অ্যাক্সেসরগুলির মধ্যে থেকে সদস্যদের অ্যাক্সেস করতে ব্যবহার করা যেতে পারে (( এমএসডিএন থেকে প্রাপ্ত )। যেহেতু এটি শ্রেণীর একটি উদাহরণ উল্লেখ করে এটি স্থির প্রকৃতির সাথে সাংঘর্ষিক, কারণ স্ট্যাটিক শ্রেণীর কোনও উদাহরণের সাথে সম্পর্কিত নয়।

একটি কর্মচক্রটি হ'ল নিম্নলিখিতটি যা আপনাকে একটি ব্যক্তিগত অভিধানের বিরুদ্ধে সূচক ব্যবহার করতে দেয় যাতে আপনাকে কেবল একটি নতুন উদাহরণ তৈরি করতে হবে এবং আপনি স্থিতিশীল অংশটি অ্যাক্সেস করতে পারেন।

    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"]

4
এটি একটি আকর্ষণীয় কাজ, কিন্তু 1) এটি পার্শ্ব-প্রতিক্রিয়াগুলি (একটি ফাঁকা দৃষ্টান্তের অবজেক্টের সৃষ্টি) উপস্থাপন করে যা কিছু পরিবেশে স্মৃতিচাপ এবং বিভাজন সৃষ্টি করতে পারে, ২) অতিরিক্ত অক্ষরগুলির দ্বারা নষ্ট new ()হওয়া একটি সিঙ্গলটনের যোগ্যতার জন্য ব্যবহার করা যেতে পারে পরিবর্তে, পছন্দ.Current
লরেন্স ওয়ার্ড

1
শুধু জুলিয়েটের উত্তর , এই প্রশ্ন কেন স্ট্যাটিক indexers সমর্থিত নয় উত্তর না। প্রথমত, প্রশ্নটি "স্ট্যাটিক ইনডেক্সার" শব্দটিকে " thisকীওয়ার্ড ব্যবহার করে এমন কিছু" হিসাবে সীমাবদ্ধ করে না এবং দ্বিতীয়ত thisবাক্য বাক্যটিতে public string this[int index]কঠোরভাবে thisপয়েন্টার ব্যবহার না করে (উদাহরণস্বরূপ পদ্ধতিগুলির শরীরে দেখা দিতে পারে) , কিন্তু টোকেনের অন্য একটি ব্যবহার this। সিনট্যাক্স public static string this[int index]পারে চেহারা একটু অনির্দিষ্ট অথবা, কিন্তু এটি এখনও দ্ব্যর্থহীন হবে।
বা ম্যাপার

2
@ ওরম্পার এটি ঠিক যেমন হতে পারে public static string class[int index]
জিম বাল্টার

আমি মনে করি আমি বিভ্রান্ত হয়ে পড়েছিলাম ভেবেছিলাম 'এই কীওয়ার্ডটি ক্লাসের বর্তমান উদাহরণকে বোঝায়। স্ট্যাটিক সদস্য ফাংশনগুলির এই পয়েন্টারটি নেই '' ব্যাখ্যা করছিলেন যেহেতু এই পয়েন্টারটির রেফারেন্সের জন্য কোনও বস্তু নেই, আপনি এটির উল্লেখটি ব্যবহার করতে পারবেন না couldn't এবং আমি আরও বলেছিলাম যে এমএসডিএনই সেই সংজ্ঞাটি ব্যবহার করে। পাবলিক স্ট্যাটিক স্ট্রিং বনাম পাবলিক স্ট্রিং কখনই আমার জেনারেটের সাথে ওভারল্যাপ হবে না কারণ এক জেনেরিক টাইপ অবজেক্টে অ্যাক্সেস করে, অন্যটি একটি ইনস্ট্যান্স অবজেক্টে অ্যাক্সেস করবে।
ল্যামোরাক

-2

কারণটি হ'ল আপনি কোন স্ট্যাটিক ইনডেক্সারের সাথে ঠিক কী সূচনা করছেন তা বোঝা বেশ শক্ত।

আপনি বলছেন যে কোডটি কোনও স্ট্যাটিক ইনডেক্সার দ্বারা উপকৃত হবে, তবে এটি কি সত্যই হবে? এটি যা করতে পারে তা হ'ল এটি পরিবর্তন করুন:

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

এটিতে:

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

যা কোনওভাবেই কোডটিকে উন্নত করে না; কোডের অনেক লাইনের দ্বারা এটি ছোট নয়, স্বতঃপূরণকে ধন্যবাদ জানানো সহজ নয় এবং এটি কম স্পষ্ট হয়, কারণ এটি আপনাকে 'সম্পত্তি' বলছে এমন কোনও কিছু পাচ্ছে এবং সেট করে দিচ্ছে তা লুকিয়ে রাখে এবং এটি পাঠককে বাধ্য করে সূচক ঠিক কী ফিরিয়ে দেয় বা সেট করে সে সম্পর্কে ডকুমেন্টেশন পড়ুন, কারণ এটি কোনওভাবেই স্পষ্ট নয় যে এটি এমন একটি সম্পত্তি যা আপনি সূচিত করছেন, উভয়ের সাথে:

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

আপনি এটি জোরে জোরে পড়তে পারবেন এবং তত্ক্ষণাত বুঝতে পারবেন কোডটি কী করে।

মনে রাখবেন যে আমরা এমন কোড লিখতে চাই যা বুঝতে সহজ (= দ্রুত), কোডটি যা দ্রুত লিখতে হয় না not আপনি যে গতিবেগে প্রকল্পগুলি সম্পন্ন করেন তার সাথে আপনি কোডটি যে গতিতে রাখতে পারেন সেই গতিটি ভুল করবেন না।


8
একমত নন। এটি নিছক একটি ধারণাগত বিষয়। কোডটি আমার মতে আরও ভাল দেখায়, যদিও এটি নিছক আমার মতামত।
আউটফ্ল্যাক করুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.