अपरिवर्तनीय प्रकारों की कमियां क्या हैं?


12

मैं खुद को अधिक से अधिक अपरिवर्तनीय प्रकारों का उपयोग करते हुए देखता हूं जब वर्ग के उदाहरणों को बदलने की उम्मीद नहीं की जाती है । इसके लिए और अधिक काम करने की आवश्यकता है (नीचे उदाहरण देखें), लेकिन एक बहुआयामी वातावरण में प्रकारों का उपयोग करना आसान बनाता है।

उसी समय, मैं शायद ही कभी अन्य अनुप्रयोगों में अपरिवर्तनीय प्रकार देखता हूं, तब भी जब उत्परिवर्तन से किसी को लाभ नहीं होगा।

प्रश्न: अन्य अनुप्रयोगों में अपरिवर्तनीय प्रकारों का उपयोग शायद ही कभी क्यों किया जाता है?

  • क्या ऐसा इसलिए है क्योंकि अपरिवर्तनीय प्रकार के लिए कोड लिखना लंबा है,
  • या मैं कुछ याद कर रहा हूं और अपरिवर्तनीय प्रकारों का उपयोग करते समय कुछ महत्वपूर्ण कमियां हैं?

वास्तविक जीवन से उदाहरण

मान लीजिए कि आप इस तरह Weatherसे एक RESTful API से प्राप्त करते हैं:

public Weather FindWeather(string city)
{
    // TODO: Load the JSON response from the RESTful API and translate it into an instance
    // of the Weather class.
}

हम आम तौर पर क्या देखेंगे (नई लाइनें और कोड को छोटा करने के लिए हटाए गए टिप्पणियां):

public sealed class Weather
{
    public City CorrespondingCity { get; set; }
    public SkyState Sky { get; set; } // Example: SkyState.Clouds, SkyState.HeavySnow, etc.
    public int PrecipitationRisk { get; set; }
    public int Temperature { get; set; }
}

दूसरी ओर, मैं इसे इस तरह से लिखूंगा, यह देखते हुए कि Weatherएपीआई से प्राप्त करना , फिर इसे संशोधित करना अजीब होगा: वास्तविक दुनिया में मौसम को बदलना Temperatureया Skyबदलना नहीं होगा, और बदलने का CorrespondingCityकोई मतलब नहीं है।

public sealed class Weather
{
    private readonly City correspondingCity;
    private readonly SkyState sky;
    private readonly int precipitationRisk;
    private readonly int temperature;

    public Weather(City correspondingCity, SkyState sky, int precipitationRisk,
        int temperature)
    {
        this.correspondingCity = correspondingCity;
        this.sky = sky;
        this.precipitationRisk = precipitationRisk;
        this.temperature = temperature;
    }

    public City CorrespondingCity { get { return this.correspondingCity; } }
    public SkyState Sky { get { return this.sky; } }
    public int PrecipitationRisk { get { return this.precipitationRisk; } }
    public int Temperature { get { return this.temperature; } }
}

3
"इसके लिए अधिक काम करने की आवश्यकता है" - उद्धरण की आवश्यकता है। मेरे अनुभव में इसे कम काम की आवश्यकता है ।
कोनराड रुडोल्फ

1
@KonradRudolph: अधिक काम से , मेरा मतलब है कि एक अपरिवर्तनीय वर्ग बनाने के लिए अधिक कोड लिखना है। मेरे प्रश्न से उदाहरण यह दर्शाता है, एक परस्पर वर्ग के लिए 7 लाइनें और एक अपरिवर्तनीय के लिए 19।
Arseni Mourzenko

यदि आप इसका उपयोग कर रहे हैं, तो आप Visual Studio में कोड स्निपेट सुविधा का उपयोग करके कोड टाइपिंग को कम कर सकते हैं। आप अपने कस्टम स्निपेट बना सकते हैं और आईडीई आपको कुछ ही कुंजियों के साथ फ़ील्ड और प्रॉपर्टी को उसी समय परिभाषित कर सकते हैं। स्केला जैसी भाषाओं में बहुउद्देशीय और बड़े पैमाने पर उपयोग किए जाने के लिए अपरिवर्तनीय प्रकार आवश्यक हैं।
मर्ट अक्काया

@Mert: सरल चीजों के लिए कोड स्निपेट महान हैं। एक कोड स्निपेट लिखना जो खेतों और संपत्तियों की टिप्पणियों के साथ एक पूर्ण वर्ग का निर्माण करेगा और सही ऑर्डर करना आसान काम नहीं होगा।
आर्सेनी मूरज़ेंको

5
मैं दिए गए उदाहरण से असहमत हूं, अपरिवर्तनीय संस्करण अधिक और अलग-अलग चीजें कर रहा है। आप एक्सेसरों के साथ संपत्तियों की घोषणा करके इंस्टेंस-लेवल वैरिएबल्स को हटा सकते हैं {get; private set;}, और यहां तक ​​कि म्यूटेबल के पास एक कंस्ट्रक्टर होना चाहिए, क्योंकि उन सभी फ़ील्ड्स को हमेशा सेट किया जाना चाहिए और आप इसे लागू क्यों नहीं करेंगे? उन दो पूरी तरह से उचित परिवर्तन करना उन्हें सुविधा और एलओसी समानता के लिए लाता है।
फशी

जवाबों:


16

मैं C # और ऑब्जेक्टिव-सी में प्रोग्राम करता हूं। मुझे वास्तव में अपरिवर्तनीय टाइपिंग पसंद है, लेकिन वास्तविक जीवन में मुझे हमेशा इसके उपयोग को सीमित करने के लिए मजबूर किया गया है, मुख्य रूप से डेटा प्रकारों के लिए, निम्न कारणों से:

  1. उत्परिवर्तनीय प्रकारों की तुलना में कार्यान्वयन का प्रयास । एक अपरिवर्तनीय प्रकार के साथ, आपको सभी गुणों के लिए तर्क की आवश्यकता वाले एक निर्माता की आवश्यकता होगी। आपका उदाहरण एक अच्छा है। कल्पना करें कि आपके पास 10 कक्षाएं हैं, जिनमें से प्रत्येक में 5-10 गुण हैं। चीजों को आसान बनाने के लिए, आप एक तरह से करने के लिए इसी में निर्माण या संशोधित अपरिवर्तनीय उदाहरणों बनाने के लिए एक बिल्डर वर्ग के लिए आवश्यकता हो सकती है StringBuilderया UriBuilderसी # में, या WeatherBuilderआपके मामले में। यह मेरे लिए मुख्य कारण है क्योंकि मेरे द्वारा डिजाइन की गई कई कक्षाएं इस तरह के प्रयास के लायक नहीं हैं।
  2. उपभोक्ता प्रयोज्य । उत्परिवर्तित प्रकार की तुलना में एक अपरिवर्तनीय प्रकार का उपयोग करना अधिक कठिन है। तात्कालिकता के लिए सभी मूल्यों को शुरू करने की आवश्यकता होती है। अपरिवर्तनीयता का अर्थ यह भी है कि हम किसी बिल्डर का उपयोग किए बिना उसके मूल्य को संशोधित करने के लिए एक विधि से उदाहरण को पारित नहीं कर सकते हैं, और यदि हमें एक बिल्डर की आवश्यकता है, तो दोष मेरे (1) में है।
  3. भाषा के ढांचे के साथ संगतता। कई डेटा फ्रेमवर्क को संचालित करने के लिए म्यूटेबल प्रकार और डिफ़ॉल्ट कंस्ट्रक्टर की आवश्यकता होती है। उदाहरण के लिए, आप LINQ-to-SQL क्वेरी को अपरिवर्तनीय प्रकारों के साथ नहीं कर सकते हैं, और आप संपादकों जैसे Windows प्रपत्र के टेक्स्टबॉक्स में संपादित किए जाने वाले गुणों को बांध नहीं सकते।

संक्षेप में, अपरिवर्तनीयता उन वस्तुओं के लिए अच्छा है जो मूल्यों की तरह व्यवहार करते हैं, या केवल कुछ गुण हैं। किसी भी चीज को अपरिवर्तनीय बनाने से पहले, आपको आवश्यक प्रयास और कक्षा की प्रयोज्यता पर विचार करना चाहिए।


11
"तात्कालिकता के लिए पहले से ही सभी मूल्यों की आवश्यकता होती है।": तब तक एक परिवर्तनशील प्रकार भी होता है, जब तक कि आप किसी वस्तु के अनैतिक क्षेत्र के साथ तैरने वाली वस्तु के जोखिम को स्वीकार नहीं करते ...
जियोर्जियो

@ जियोर्जियो परस्पर प्रकार के लिए, डिफॉल्ट कंस्ट्रक्टर को उदाहरण को डिफ़ॉल्ट स्थिति में इनिशियलाइज़ करना चाहिए और इंस्टेंटेशन के बाद इंस्टेंस की स्थिति को बदल दिया जा सकता है।
tia

8
एक अपरिवर्तनीय प्रकार के लिए आपके पास एक ही डिफ़ॉल्ट निर्माता हो सकता है, और बाद में किसी अन्य निर्माता का उपयोग करके प्रतिलिपि बना सकता है। यदि डिफ़ॉल्ट मान उत्परिवर्ती प्रकार के लिए मान्य हैं, तो उन्हें अपरिवर्तनीय प्रकार के लिए भी मान्य होना चाहिए क्योंकि दोनों ही मामलों में आप एक ही इकाई के लिए मॉडलिंग कर रहे हैं। या क्या अंतर है?
जियोर्जियो

1
एक और बात पर विचार करने के लिए क्या प्रकार का प्रतिनिधित्व करता है। डेटा अनुबंध इन सभी बिंदुओं के कारण अच्छे अपरिवर्तनीय प्रकारों के लिए नहीं बनते हैं, लेकिन सेवा प्रकार जो निर्भरता के साथ आरंभीकृत हो जाते हैं या केवल डेटा पढ़ते हैं और फिर संचालन करना अपरिवर्तनीयता के लिए बहुत अच्छा है क्योंकि संचालन लगातार प्रदर्शन करेंगे और सेवा की स्थिति नहीं हो सकती है कि जोखिम के लिए बदल दिया है।
केविन

1
मैं वर्तमान में एफ # में कोड करता हूं, जहां अपरिवर्तनीयता डिफ़ॉल्ट है (इसलिए लागू करना आसान है)। मुझे पता है कि आपकी बात 3 बड़ी बाधा है। जैसे ही आप अधिकांश मानक .Net पुस्तकालयों का उपयोग करते हैं, आपको हुप्स के माध्यम से कूदने की आवश्यकता होगी। (और अगर वे प्रतिबिंब का उपयोग करते हैं और इस तरह से अपरिवर्तनीयता को दरकिनार करते हैं ... argh!)
गुरन

5

आमतौर पर भाषाओं में निर्मित अपरिवर्तनीय प्रकार जो अपरिवर्तनशीलता के इर्द-गिर्द नहीं घूमते हैं, वांछित परिवर्तन को व्यक्त करने के लिए कुछ "बिल्डर" प्रकार की वस्तु की आवश्यकता होने पर संभावित उपयोग करने के लिए अधिक डेवलपर समय खर्च करने की आवश्यकता होगी (इसका मतलब यह नहीं है कि समग्र काम अधिक होगा, लेकिन इन मामलों में लागत में बढ़ोतरी है)। इस बात की परवाह किए बिना कि क्या यह वास्तव में अपरिवर्तनीय प्रकार बनाने में आसान है या नहीं, यह हमेशा गैर-तुच्छ डेटा प्रकारों के लिए कुछ प्रसंस्करण और मेमोरी ओवरहेड की आवश्यकता होगी।

बनाना साइड इफेक्ट्स से रहित

यदि आप उन भाषाओं में काम कर रहे हैं जो अपरिवर्तनीयता के आसपास नहीं घूमती हैं, तो मुझे लगता है कि व्यावहारिक दृष्टिकोण हर एक डेटा प्रकार को अपरिवर्तनीय बनाने की तलाश नहीं है। संभावित रूप से अधिक उत्पादक मानसिकता जो आपको एक ही लाभ प्रदान करती है, वह है आपके सिस्टम में उन कार्यों की संख्या को अधिकतम करने पर ध्यान केंद्रित करना जो शून्य साइड इफेक्ट का कारण बनते हैं

एक सरल उदाहरण के रूप में, यदि आपके पास एक फ़ंक्शन है जो इस तरह के दुष्प्रभाव का कारण बनता है:

// Make 'x' the absolute value of itself.
void make_abs(int& x);

तब हमें एक अपरिवर्तनीय पूर्णांक डेटा प्रकार की आवश्यकता नहीं होती है जो उस फ़ंक्शन को साइड इफेक्ट से बचने के लिए पोस्ट-इनिशियलाइज़ेशन असाइनमेंट जैसे ऑपरेटरों को मना करती है। हम बस यह कर सकते हैं:

// Returns the absolute value of 'x'.
int abs(int x);

अब फ़ंक्शन xइसके दायरे से बाहर या उसके साथ कुछ भी गड़बड़ नहीं करता है , और इस तुच्छ मामले में हमने अप्रत्यक्ष / अलियासिंग से जुड़े किसी भी ओवरहेड से बचने के लिए कुछ चक्रों को भी मुंडा दिया हो सकता है। बहुत कम से कम दूसरा संस्करण पहले की तुलना में अधिक कम्प्यूटेशनल रूप से महंगा नहीं होना चाहिए।

वे चीजें जो कॉपी करने के लिए महंगी हैं

निश्चित रूप से ज्यादातर मामलों में यह तुच्छ नहीं है अगर हम एक कार्य कारण दुष्प्रभाव से बचना चाहते हैं। एक जटिल वास्तविक दुनिया का उपयोग मामला इस तरह हो सकता है:

// Transforms the vertices of the specified mesh by
// the specified transformation matrix.
void transform(Mesh& mesh, Matrix4f matrix);

जिस बिंदु पर मेष को एक सौ सौ से अधिक बहुभुजों के साथ एक सौ मेगाबाइट मेमोरी की आवश्यकता हो सकती है, यहां तक ​​कि अधिक कोने और किनारों, कई बनावट के नक्शे, मॉर्फ लक्ष्य आदि, यह वास्तव में महंगा होगा कि इसे बनाने के लिए पूरे जाल की नकल करें। transformसमारोह के साइड इफेक्ट्स से मुक्त, जैसे:

// Returns a new version of the mesh whose vertices been 
// transformed by the specified transformation matrix.
Mesh transform(Mesh mesh, Matrix4f matrix);

और यह इन मामलों में है जहां इसकी संपूर्णता में कुछ कॉपी करना आम तौर पर एक महाकाव्य ओवरहेड होगा जहां मैंने इसे Meshलगातार डेटा संरचना में बदलने के लिए उपयोगी पाया है और एनालॉग "बिल्डर" के साथ एक अपरिवर्तनीय प्रकार इसके संशोधित संस्करण बनाने के लिए इतना है कि यह बस उथले प्रतिलिपि और संदर्भ गणना भागों को देख सकते हैं जो अद्वितीय नहीं हैं। यह मेष कार्यों को लिखने में सक्षम होने के ध्यान के साथ है, जो दुष्प्रभावों से मुक्त हैं।

लगातार डेटा संरचनाएं

और इन मामलों में जहां सब कुछ कॉपी करना इतना अविश्वसनीय रूप से महंगा है, मुझे Meshवास्तव में भुगतान करने के लिए एक अपरिवर्तनीय डिजाइन करने का प्रयास मिला, भले ही इसकी थोड़ी सी खड़ी लागत थी, क्योंकि यह थ्रेड सुरक्षा को सरल नहीं करता था। यह गैर-विनाशकारी संपादन को भी सरल करता है (उपयोगकर्ता को अपनी मूल प्रति को संशोधित किए बिना मेष संचालन को परत करने की अनुमति देता है), पूर्ववत सिस्टम (अब पूर्ववत व्यवस्था केवल मेमोरी को उड़ाने के बिना एक ऑपरेशन द्वारा किए गए परिवर्तनों से पहले जाल की एक अपरिवर्तनीय प्रतिलिपि संग्रहीत कर सकती है) उपयोग), और अपवाद-सुरक्षा (अब यदि उपरोक्त फ़ंक्शन में कोई अपवाद होता है, तो फ़ंक्शन को वापस रोल नहीं करना पड़ता है और इसके सभी साइड इफेक्ट्स को पूर्ववत करना पड़ता है क्योंकि इससे कोई शुरुआत नहीं हुई थी)।

मैं इन मामलों में विश्वासपूर्वक कह ​​सकता हूं कि इन भारी डेटा संरचनाओं को अपरिवर्तनीय बनाने में लगने वाले समय की लागत की तुलना में अधिक समय की बचत हुई है, क्योंकि मैंने इन नए डिजाइनों के रखरखाव की लागत की तुलना उन पूर्व के खिलाफ की है जो परिवर्तनशीलता और कार्यों के चारों ओर घूमते हैं और दुष्प्रभाव पैदा करते हैं, और पूर्व के परिवर्तनशील डिजाइनों में अधिक समय लगता है और मानव त्रुटि के लिए कहीं अधिक संभावित थे, विशेष रूप से ऐसे क्षेत्रों में जो क्रंच समय के दौरान डेवलपर्स के लिए लुभावना होते हैं, जैसे अपवाद-सुरक्षा।

इसलिए मुझे लगता है कि इन मामलों में अपरिवर्तनीय डेटा प्रकार वास्तव में भुगतान करते हैं, लेकिन आपके सिस्टम में अधिकांश कार्यों को साइड इफेक्ट से मुक्त बनाने के लिए सब कुछ अपरिवर्तनीय नहीं होना चाहिए। बहुत सी चीजें काफी सस्ती हैं जो सिर्फ पूर्ण में कॉपी हैं। इसके अलावा कई वास्तविक दुनिया के अनुप्रयोगों को यहां और वहां कुछ साइड इफेक्ट्स की आवश्यकता होगी (बहुत कम से कम एक फ़ाइल को बचाने की तरह), लेकिन आमतौर पर ऐसे कई कार्य हैं जो साइड इफेक्ट्स से रहित हो सकते हैं।

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

अपरिवर्तनीय ओवरहेड

अब वैचारिक रूप से उत्परिवर्तित संस्करणों में हमेशा दक्षता में बढ़त होगी। वहाँ हमेशा कम्प्यूटेशनल ओवरहेड अपरिवर्तनीय डेटा संरचनाओं के साथ जुड़ा हुआ है। लेकिन मैंने इसे ऊपर वर्णित मामलों में एक योग्य विनिमय पाया, और आप ओवरहेड को प्रकृति में पर्याप्त रूप से न्यूनतम बनाने पर ध्यान केंद्रित कर सकते हैं। मैं उस प्रकार के दृष्टिकोण को पसंद करता हूं जहां शुद्धता आसान हो जाती है और अनुकूलन आसान होने के बजाय अनुकूलन कठिन हो जाता है लेकिन शुद्धता कठिन हो जाती है। यह कोड के बारे में अवमूल्यन करने के रूप में लगभग नहीं है कि कोड पर कुछ और धुन अप की आवश्यकता के लिए पूरी तरह से सही ढंग से कार्य करता है जो पहली बार में सही ढंग से काम नहीं करता है चाहे वह कितनी जल्दी अपने गलत परिणामों को प्राप्त करता हो।


3

एकमात्र दोष जो मैं सोच सकता हूं, वह यह है कि अपरिवर्तनीय डेटा के सिद्धांत में उपयोग करने योग्य लोगों की तुलना में धीमा हो सकता है - यह एक नया उदाहरण बनाने के लिए धीमा है, और पिछले एक को इकट्ठा करने की तुलना में मौजूदा को संशोधित करना है।

दूसरी "समस्या" यह है कि आप केवल अपरिवर्तनीय प्रकारों का उपयोग नहीं कर सकते। अंत में आपको राज्य का वर्णन करना होगा और आपको ऐसा करने के लिए परस्पर प्रकारों का उपयोग करना होगा - बिना राज्य को बदले आप कोई काम नहीं कर सकते।

लेकिन अभी भी सामान्य नियम अपरिवर्तनीय प्रकारों का उपयोग करना है जहाँ आप कर सकते हैं और केवल तभी परिवर्तन कर सकते हैं जब वास्तव में ऐसा करने का कोई कारण हो ...

और इस सवाल का जवाब देने के लिए " अपरिवर्तनीय प्रकार का उपयोग अन्य अनुप्रयोगों में शायद ही कभी क्यों किया जाता है? " - मुझे वास्तव में नहीं लगता कि वे हैं ... जहाँ भी आप सभी को अपनी कक्षाओं को अपरिवर्तनीय बनाने की अनुशंसा करते हैं, उदाहरण के लिए ... http://www.javapractices.com/topic/TopicAction.do?Id=29


1
आपकी दोनों समस्याएं हालांकि हास्केल में नहीं हैं।
फ्लोरियन मार्गाइन

@FlorianMargaine क्या आप विस्तृत कर सकते हैं?
म्रिचो

सुस्ती स्मार्ट कंपाइलर के लिए धन्यवाद नहीं है। और हास्केल में, यहां तक ​​कि I / O एक अपरिवर्तनीय एपीआई के माध्यम से है।
फ्लोरियन मार्गाइन

2
गति की तुलना में एक अधिक मूलभूत समस्या यह है कि अपरिवर्तनीय वस्तुओं के लिए पहचान बनाए रखना मुश्किल होता है, जबकि उनकी स्थिति बदल जाती है। यदि किसी Carविशेष भौतिक ऑटोमोबाइल के स्थान के साथ एक उत्परिवर्तनीय वस्तु को लगातार अपडेट किया जाता है, तो यदि मेरे पास उस वस्तु का संदर्भ है तो मैं उस ऑटोमोबाइल के ठिकाने का पता जल्दी और आसानी से लगा सकता हूं। यदि Carअपरिवर्तनीय थे, तो वर्तमान ठिकाने का पता लगाना बहुत कठिन होगा।
सुपरकैट

कंपाइलर को यह पता लगाने के लिए आपको कभी-कभी काफी चालाकी से कोड करना पड़ता है कि पिछली वस्तु का कोई संदर्भ नहीं बचा है और इस तरह इसे संशोधित किया जा सकता है, या वनों की कटाई को बदल सकता है, एट अल। खासकर बड़े कार्यक्रमों में। और जैसा @supercat कहता है, पहचान वास्तव में एक समस्या बन सकती है।
मैके

0

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

  • एक अपरिवर्तनीय वस्तु के लिए एक परस्पर संदर्भ का उपयोग करना
  • एक उत्परिवर्तनीय वस्तु के लिए एक अपरिवर्तनीय संदर्भ का उपयोग करना
  • एक उत्परिवर्तित वस्तु का एक परस्पर संदर्भ का उपयोग करना

पहले का उपयोग करना किसी वस्तु को वर्तमान स्थिति के अपरिवर्तनीय स्नैपशॉट बनाने के लिए आसान बनाता है। दूसरे का उपयोग करना किसी वस्तु के लिए वर्तमान स्थिति का जीवंत दृश्य बनाना आसान बनाता है। तीसरे का उपयोग करना कभी-कभी कुछ मामलों में उन मामलों में अधिक कुशल बना सकता है जहां अपरिवर्तनीय स्नैपशॉट के लिए बहुत कम अपेक्षा है और न ही लाइव दृश्य।

इस तथ्य से परे कि एक अपरिवर्तनीय वस्तु के लिए एक परस्पर संदर्भ का उपयोग करके संग्रहीत स्टेट को अपडेट करना अक्सर एक उत्परिवर्तित वस्तु का उपयोग करके संग्रहीत स्टेट को अपडेट करने की तुलना में धीमा होता है, एक उत्परिवर्तित संदर्भ का उपयोग करके एक को राज्य के सस्ते लाइव व्यू के निर्माण की संभावना से गुजरना होगा। यदि किसी को लाइव दृश्य बनाने की आवश्यकता नहीं होगी, तो यह समस्या नहीं है; अगर, हालांकि, किसी को एक लाइव दृश्य बनाने की आवश्यकता होगी, एक अपरिवर्तनीय संदर्भ का उपयोग करने में असमर्थता दृश्य के साथ सभी संचालन करेगी - दोनों पढ़ता है और लिखता है- वे की तुलना में धीमी गति से अन्यथा होगा। यदि अपरिवर्तनीय स्नैपशॉट की आवश्यकता लाइव दृश्यों की आवश्यकता से अधिक है, तो अपरिवर्तनीय स्नैपशॉट का बेहतर प्रदर्शन लाइव दृश्यों के लिए प्रदर्शन हिट को सही ठहरा सकता है, लेकिन अगर किसी को लाइव विचारों की आवश्यकता होती है और उसे स्नैपशॉट की आवश्यकता नहीं होती है, तो उत्परिवर्तित वस्तुओं के लिए अपरिवर्तनीय संदर्भ का उपयोग करना तरीका है। जाना।


0

आपके मामले में जवाब मुख्य रूप से है क्योंकि C # को इम्युनिटी के लिए खराब सपोर्ट है ...

यह बहुत अच्छा होगा यदि:

  • सब कुछ डिफ़ॉल्ट रूप से अपरिवर्तनीय होगा जब तक कि अन्यथा नोट न किया जाए (यानी एक 'उत्परिवर्तित' कीवर्ड), अपरिवर्तनीय और परिवर्तनशील मिश्रण को भ्रामक है

  • परिवर्तनशील तरीकों ( With) स्वचालित रूप से उपलब्ध हो जाएगा - हालांकि यह पहले से ही हासिल किया जा सकता है देखने के साथ

  • एक विशिष्ट विधि कॉल का परिणाम कहने का एक तरीका होगा (यानी ImmutableList<T>.Add) को खारिज नहीं किया जा सकता है या कम से कम एक चेतावनी का उत्पादन करेगा

  • और मुख्य रूप से यदि कंपाइलर जहां संभव हो सके, जहां अनुरोध किया जाता है, वहां अपरिवर्तनीयता सुनिश्चित करें (देखें https://github.com/dotnet/roslyn/issues/159 )


1
तीसरा बिंदु फिर से, ReSharper में एक MustUseReturnValueAttributeकस्टम विशेषता है जो वास्तव में ऐसा करता है। PureAttributeएक ही प्रभाव है और इसके लिए भी बेहतर है।
सेबेस्टियन रेडल

-1

अपरिवर्तनीय प्रकार अन्य अनुप्रयोगों में इतने कम क्यों उपयोग किए जाते हैं?

अज्ञान? अनुभवहीनता?

अपरिवर्तनीय वस्तुओं को आज व्यापक रूप से श्रेष्ठ माना जाता है, लेकिन यह अपेक्षाकृत हाल ही में विकसित हुआ है। इंजीनियर जो आज तक नहीं रखे हैं, या वे केवल 'जो वे जानते हैं' में फंस गए हैं, उनका उपयोग नहीं करेंगे। और उन्हें प्रभावी ढंग से उपयोग करने के लिए डिज़ाइन में थोड़ा बदलाव होता है। यदि एप्लिकेशन पुराने हैं, या इंजीनियर डिज़ाइन कौशल में कमजोर हैं, तो उनका उपयोग करना अजीब या अन्यथा परेशानी भरा हो सकता है।


"इंजीनियर जो आज तक नहीं रखे हैं": कोई यह कह सकता है कि एक इंजीनियर को गैर-मुख्यधारा की तकनीकों के बारे में भी सीखना चाहिए। अपरिवर्तनशीलता का विचार केवल हाल ही में मुख्यधारा बन रहा है, लेकिन यह एक बहुत पुराना विचार है और योजना, एसएमएल, हास्केल जैसी पुरानी भाषाओं द्वारा समर्थित (यदि लागू नहीं है) है। इसलिए जो भी मुख्यधारा की भाषाओं से परे देखने के आदी हैं, वे 30 साल पहले भी इसके बारे में जान सकते थे।
जियोर्जियो

@ जियोर्जियो: कुछ देशों में, कई इंजीनियर अभी भी C # कोड को LINQ के बिना लिखते हैं, FP के बिना, पुनरावृत्तियों के बिना और जेनरिक के बिना, इसलिए वास्तव में, वे किसी भी तरह से 2003 के बाद से C # के साथ जो कुछ भी हुआ उसे याद करते हैं। अगर उन्हें अपनी पसंद की भाषा भी नहीं आती है। , मैं शायद ही किसी भी गैर-मुख्यधारा की भाषा को जानने के लिए उनकी कल्पना करता हूं।
आर्सेनी मौरज़ेंको

@ मेनमा: अच्छा है कि आपने इटैलिक में शब्द इंजीनियर लिखा है ।
जियोर्जियो

@ जियोर्जियो: मेरे देश में, उन्हें आर्किटेक्ट , सलाहकार और बहुत सारे अन्य शब्द भी कहा जाता है , कभी भी इटैलिक में नहीं लिखा जाता है। जिस कंपनी में मैं वर्तमान में काम कर रहा हूं, मुझे विश्लेषक डेवलपर कहा जाता है , और मुझे अपना समय सीएसएस को भद्दा विरासत HTML कोड लिखने के लिए खर्च करने की उम्मीद है। नौकरी के खिताब इतने सारे स्तरों पर परेशान कर रहे हैं।
आर्सेनी मौरज़ेंको 10

1
@ मेनमा: मैं सहमत हूं। इंजीनियर या सलाहकार जैसे शीर्षक अक्सर केवल व्यापक रूप से स्वीकृत अर्थ के साथ buzzwords होते हैं। वे अक्सर किसी को या उनकी स्थिति को वास्तव में है की तुलना में अधिक महत्वपूर्ण / प्रतिष्ठित बनाने के लिए उपयोग किया जाता है।
जियोर्जियो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.