एक निर्माता पर [शुद्ध] का उपयोग कब करें?


19

मैं .NET में कोड कॉन्ट्रैक्ट्स के बारे में सीख रहा हूं, और मैं शुद्ध कंस्ट्रक्टर्स के विचार को समझने की कोशिश कर रहा हूं। कोड ठेके प्रलेखन कहता है:

अनुबंध के भीतर कहे जाने वाले सभी तरीके शुद्ध होने चाहिए; यही है, वे किसी भी preexisting राज्य को अद्यतन नहीं करना चाहिए। शुद्ध विधि में प्रवेश के बाद बनाई गई वस्तुओं को संशोधित करने के लिए एक शुद्ध विधि की अनुमति है।

और PureAttributeप्रलेखन राज्यों:

इंगित करता है कि एक प्रकार या विधि शुद्ध है, अर्थात, यह कोई भी दृश्यमान परिवर्तन नहीं करता है।

मैं इन कथनों को समझता हूं जब यह तरीकों की बात आती है, लेकिन निर्माणकर्ताओं के बारे में क्या? मान लीजिए कि आपके पास इस तरह एक वर्ग था:

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

यह निर्माता स्पष्ट रूप से नई Fooवस्तु की स्थिति को प्रभावित करता है , लेकिन इसका कोई अन्य दुष्प्रभाव नहीं है (उदाहरण के लिए यह किसी भी पैरामीटर में हेरफेर नहीं करता है या किसी गैर-शुद्ध तरीकों को कॉल नहीं करता है)। यह कोई उम्मीदवार है [Pure]या नहीं? [Pure]एक निर्माता पर एक विशेषता रखने का क्या महत्व है , और मुझे अपने कोड में कब करना चाहिए?

जवाबों:


14

आप इसके साथ एक विधि सजाते हैं [Pure]:

  • यदि विधि का दुष्प्रभाव नहीं है। उदाहरण के लिए, यदि विधि किसी डेटाबेस तक पहुँचती है और इसे संशोधित करती है या इसका परिणाम डेटाबेस पर निर्भर करता है, तो यह शुद्ध नहीं है।

  • और अगर आप इसे कोड कॉन्ट्रैक्ट में उपयोग करने की उम्मीद करते हैं। उदाहरण के लिए, यदि विधि शुद्ध है , लेकिन आपके पास कोड अनुबंध में इसका उपयोग करने का कोई इरादा नहीं है, तो जोड़ने [Pure]से कोई लाभ नहीं होगा और आपके कोड को तेज नहीं करेगा।

जहां तक ​​यह कंस्ट्रक्टर्स की चिंता है, ऐसा लगता है कि उन्हें .NET में शुद्ध माना जाता है और एक स्पष्ट विशेषता की आवश्यकता नहीं है। मैंने .NET फ्रेमवर्क स्रोत में कई निर्माणकर्ताओं को देखा, जैसे कि DateTime, और उनके पास [Pure]विशेषता नहीं है ।

मुझे लगता है कि यह कई कारणों से किया जाता है:

  • [Pure]एक अनुबंध में वर्ग / संरचना का उपयोग करने में सक्षम होने के लिए विशेषता के साथ एक पैरामीटर रहित निर्माता लिखना बहुत अधिक अव्यावहारिक हो सकता है ।

  • कुछ, जैसे कि String, स्पष्ट निर्माता नहीं हैं।

  • कंस्ट्रक्टरों को कोड अनुबंधों के बाहर भी विशेष उपचार प्राप्त होता है; उदाहरण के लिए, आप उनके अंदर अपवादों को फेंकने की उम्मीद नहीं कर रहे हैं

  • [Pure]सिर्फ एक सम्मेलन है जो यहां आपके जीवन को सरल बनाने के लिए है, लेकिन यह सुनिश्चित करने के लिए कोई वास्तविक स्थैतिक जाँच नहीं है कि इस विशेषता के साथ सजाया गया तरीका शुद्ध है। void DestroyDatabase()शुद्ध होने के रूप में सजाया जा सकता है, और कोड अनुबंध कुछ भी गलत नहीं देखेंगे।

    वर्तमान में कोड कॉन्ट्रैक्ट्स का कोई घटक नहीं है जो जाँचता है कि क्या घोषित किए गए तरीके वास्तव में शुद्ध हैं। इस प्रकार यदि एक प्रोग्रामर ने एक विधि को [शुद्ध] से सजाया है, तो यह सिर्फ विश्वास है।

    से कोड # 5 संविदा: विधि पवित्रता

  • .NET फ्रेमवर्क में ही ऐसे कंस्ट्रक्टर हैं जो शुद्ध नहीं हैं। उदाहरण के लिए, List<T>(IEnumerable<T> collection)वास्तव में अशुद्ध है यदि संग्रह के माध्यम से लूपिंग के दुष्प्रभाव होते हैं।

  • संविदा चिल्लाओ को सरल रखा जाए। मैं आसानी से एक अनुबंध की कल्पना कर सकता हूं Contract.Requires(!string.IsNullOrEmpty(name)), जैसे कि स्थिर string.IsNullOrEmptyशुद्ध घोषित करने के अच्छे कारण हैं ।

    दूसरी ओर, यदि आपको StringBuilderस्ट्रिंग का निर्माण करने के लिए एक की आवश्यकता है, तो आप अपने व्यवसाय वर्ग के इंस्टेंस विधि को कॉल करके कुछ के लिए जाँच करेंगे, तो आप शायद अनुबंधों का दुरुपयोग कर रहे हैं। यही कारण StringBuilder.ToStringहै कि शुद्ध के रूप में चिह्नित नहीं किया जाता है, भले ही यह हो सकता है (यह है?)


सिस्टम प्रकार के कई कोड कॉन्ट्रैक्ट चेकर द्वारा ग्रहण किए जाते हैं, जिसमें " किसी भी विधि जिसका पूरी तरह से योग्य नाम" System.Diagnostics.Contracts.Contract "," System.String "," System.IO.Path "या" सिस्टम "शामिल है .Type " "। दुर्भाग्य से, मुझे यकीन नहीं है कि जब कोड अनुबंधों की बात आती है तो .NET प्रकार देखना बहुत उपयोगी होता है।
16

3
पवित्रता उन चीजों में से एक है जहां सभी कोड को भी शुद्ध होना चाहिए, या कॉल करने वाला "शुद्ध" नहीं है। मुझे विश्वास करना मुश्किल है कि सभी निर्माणकर्ताओं को डिफ़ॉल्ट रूप से शुद्ध माना जाता है।
फ्रैंक हिलमैन

@FrankHileman: मुझे भी। मेरे पास अभी C # कंपाइलर नहीं है, लेकिन एक रचनाकार और किसी भी [Pure]विशेषता के साथ एक वर्ग लिखने के लिए पर्याप्त होगा , और एक निश्चित उत्तर के लिए इसे अनुबंध में कहीं और उपयोग करें।
आर्सेनी मूरज़ेंको

1

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


तो एक शुद्ध निर्माता एक शुद्ध विधि है जिसे वर्तमान वर्ग की स्थिति को बदलने की अनुमति है, जब तक कि यह शुद्ध होने की अन्य शर्तों को पूरा नहीं करता है? बीटीडब्ल्यू, संपत्ति उत्परिवर्तनीय है क्योंकि मैं इस बात पर जोर देना चाहता था कि यह वर्ग स्वयं शुद्ध नहीं है।
pswg

@pswg: आपने एक दिलचस्प सवाल बनाया, जिसका जवाब शायद Microsoft को देना होगा। मान लीजिए कि कंस्ट्रक्टर ने एक विधि का इस्तेमाल किया, जिसने उत्परिवर्तनीय संपत्ति को संशोधित किया; क्या कंस्ट्रक्टर अभी भी शुद्ध होगा? मुझे लगता है कि तकनीकी रूप से यह बाहरी दर्शकों के लिए "अदृश्य" होने के बावजूद नहीं होगा। चूँकि आपके मूल उदाहरण में कोई अन्य कोड नहीं लगाया गया है, यह किसी भी परिभाषा से शुद्ध होना चाहिए जिसे मैं सोच सकता हूँ।
फ्रैंक हिलमैन

@pswg: सिवाय इसके कि प्रॉपर्टी सेट भी एक मेथड कॉल है .. मुझे लगता है कि आपको MSDN मंचों पर पूछना चाहिए।
फ्रैंक हिलमैन

मुझे लगता है कि अगर पवित्रता का केंद्रीय विचार है कि विधि कोई अवलोकन योग्य परिवर्तन करती है या नहीं , तो उस अर्थ में, चाहे वह गैर-शुद्ध तरीकों को बुलाए या नहीं, जब तक कि किसी भी कॉलर द्वारा परिवर्तन नहीं देखे जा सकते , यह अभी भी एक शुद्ध तरीका होगा।
pswg

@pswg: यह सार परिभाषा है। लेकिन अगर मैं इन चीजों के लिए एक विश्लेषक लिख रहा था, तो संभवत: एक गैर-शुद्ध विधि कॉल को कॉल करने वाले को गैर-शुद्ध बनाने के लिए भी माना जाएगा। सिर्फ कार्यान्वयन की सादगी के लिए। फिर सवाल यह है कि, एक कंस्ट्रक्टर एक सामान्य विधि कॉल है, या विश्लेषण कितना गहरा है।
फ्रैंक हिलमैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.