2011-12-20 9 views
19

यदि मैं सार्वजनिक संपत्ति के सेटर के निजी संशोधक के सेटटर के एक्सेस संशोधक को निजी से सार्वजनिक में बदलता हूं, तो क्या यह अन्य असेंबली में किसी भी ब्रेकिंग परिवर्तन का कारण बनता है जो इसे संदर्भित करता है?क्या यह एक तोड़ने वाला परिवर्तन है जो सार्वजनिक संपत्ति के एक्सेस संशोधक को संशोधित करता है?

+0

नहीं, वे अन्य असेंबली पहले संपत्ति का उपयोग करने में सक्षम नहीं थे। –

+0

@ हंस, संपत्ति का गेटर्स सार्वजनिक है इसलिए अन्य असेंबली इसका उपयोग कर सकते हैं। – mkus

+0

ठीक है, आप गेटटर को बदल नहीं रहे हैं? जेआईटी कंपाइलर को बदली हुई संपत्ति घोषणा के साथ कोई परेशानी नहीं है। –

उत्तर

31

अद्यतन: This question was the topic of my blog in January 2012। महान सवाल के लिए धन्यवाद!


मुझे लगता है कि "ब्रेकिंग परिवर्तन" क्या आपका मतलब द्वारा "जब मैं कोड है कि इस विधानसभा पर निर्भर पुनः संकलित करें, कोड है कि अभी भी संकलित करने के लिए इस्तेमाल किया संकलित करता है?"

उस परिभाषा के अनुसार, सख्ती से बोलते हुए, हां, एक संपत्ति सेटर सार्वजनिक बनाना जो निजी होता था वह एक तोड़ने वाला परिवर्तन होता है। मान लीजिए आप इस कोड है:

// Assembly Alpha 
public class Charlie 
{ 
    public int P { get; private set; } 
} 
public class Delta 
{ 
    public int P { get; set; } 
} 

और फिर एक और विधानसभा का संदर्भ देता है अल्फा में:

// Assembly Echo 
class Foxtrot 
{ 
    static void M(Action<Charlie> f) {} 
    static void M(Action<Delta> f) {} 
    static void Golf() 
    { 
     M(y=>{y.P = 123;}); 
    } 
} 

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

अब आप असेंबली अल्फा बदलते हैं ताकि चार्ली.पी का सेटटर सार्वजनिक हो। आप इको recompile। अब आपको एक अधिभार रिज़ॉल्यूशन त्रुटि मिलती है क्योंकि एम के दोनों अधिभार समान रूप से वैध हैं और न ही दूसरे की तुलना में बेहतर है। अल्फा में परिवर्तन के कारण इको का संकलन विफल रहता है। अल्फा में आपका परिवर्तन एक तोड़ने वाला परिवर्तन था।

सवाल यह नहीं है कि "क्या यह एक तोड़ने वाला परिवर्तन है?" यह स्पष्ट रूप से है; लगभग हर परिवर्तन कुछ प्रकार का तोड़ने वाला परिवर्तन होता है। सवाल यह होना चाहिए कि ब्रेकिंग बदलाव वास्तव में अभ्यास में किसी को तोड़ देगा, और यदि हां, तो नई सुविधा के लाभ की तुलना में ब्रेक को ठीक करने की क्या कीमत है?

+2

ब्रावो के साथ क्या हुआ? – kvb

+20

@kvb: मुझे एक बार बुकिंग करने के लिए एक एयरलाइन फोन करना पड़ा और फोन पर सहायक महिला ने कहा, "यदि कोई समस्या है तो यहां आपकी पुष्टि संख्या है: 153ADN6, यह 1-5-3-अल्फा-डॉग-नवंबर- 6 ", और मैंने कहा" धन्यवाद, लेकिन डेल्टा अंतरराष्ट्रीय रेडियो कोड डी के लिए शब्द नहीं है? " और उसने कहा "* हम इस एयरलाइन पर यह शब्द नहीं कहते हैं! *" मैं आपको बताता हूं, एक एयरलाइन पर फोन पर * व्यक्ति * प्राप्त करना काफी कठिन है; बूट करने के लिए अंतरराष्ट्रीय रेडियो वर्णमाला को जानता है जो एक स्मार्ट और हास्यास्पद हो रही है वास्तव में एक दुर्लभता है। –

+2

अभी भी मजेदार होगा अगर यह वास्तव में डेल्टा था जिसे आप बुला रहे थे। –

5

यह इस बात पर निर्भर करता है कि आप "ब्रेकिंग चेंज" के बारे में कितना सख्त होना चाहते हैं।

एक परिभाषा यह है: क्या यह रेफरिंग कोड के निर्माण या निष्पादन को तोड़ देता है।

दूसरा, क्या दूसरा कोड यह निर्धारित कर सकता है कि आपने परिवर्तन किया है।

पहली परिभाषा के अनुसार, यह एक तोड़ने वाला बदलाव नहीं है। दूसरी परिभाषा के अनुसार, यह एक तोड़ने वाला परिवर्तन है।

+1

[एरिक का उत्तर] (http://stackoverflow.com/a/8581029) और [जेफरी का उत्तर] (http://stackoverflow.com/a/8581019) किनारे के मामलों की पेशकश करता है जहां यह संकलन तोड़ देगा। – Brian

0

मुझे नहीं लगता लेकिन आपको पता होना चाहिए कि इस सेटटर को निजी बनाने के लिए क्या ज्ञान है। पुस्तकालय उपभोक्ताओं और encapsulation में प्रवेश संशोधक महत्वपूर्ण हैं।

3

यह हो सकता है कि अगर अन्य असेंबली सेटटर की उपस्थिति के लिए परीक्षण करने के लिए प्रतिबिंब का उपयोग करें।

लेकिन प्रारंभिक बाउंड कोड नहीं टूट जाएगा।

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

2

चूंकि संपत्ति की दृश्यता बढ़ी है अब स्थैतिक रूप से जुड़ी असेंबली और स्थैतिक संदर्भों के साथ कोई समस्या नहीं होनी चाहिए - उन असेंबली ने अभी तक आपकी संपत्ति को केवल पढ़ने के लिए ही माना है और वे ऐसा करते रहेंगे।

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

उदाहरण के लिए

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

17

यह एक तोड़ने वाला परिवर्तन है, जिससे मौजूदा कोड अब संकलित नहीं हो सकता है।

कुछ भाषाएं आपको सभी दृश्यमान एक्सेसर्स को ओवरराइड किए बिना किसी संपत्ति को ओवरराइड करने की अनुमति नहीं देती हैं। वीबी ऐसी भाषा है।

आप निम्नलिखित सी # वर्ग है कहते हैं:

Class B : Inherits TestLibrary.A 
    Public Overrides ReadOnly Property X As Integer 
     Get 
      Return MyBase.X 
     End Get 
    End Property 
End Class 

सूचना ReadOnly संपत्ति पर संशोधक:

namespace TestLibrary 
    public class A { 
     public virtual int X { 
      get { return 0; } 
      private set { Console.WriteLine("A.set_X called."); } 
     } 
    } 
} 

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

Property without a 'ReadOnly' or 'WriteOnly' specifier must provide both a 'Get' and a 'Set'.

, अपने सी # कक्षा में सेटर से private संशोधक को दूर: आप इसे बाहर छोड़ देते हैं तो आप एक संकलन समय त्रुटि मिलती है

namespace TestLibrary 
    public class A { 
     public virtual int X { 
      get { return 0; } 
      set { Console.WriteLine("A.set_X called."); } 
     } 
    } 
} 

अब आप एक संकलन समय मिल जाएगा अपने VB कोड में त्रुटि:

'Public Overrides ReadOnly Property X As Integer' cannot override 'Public Overridable Property X As Integer' because they differ by 'ReadOnly' or 'WriteOnly'.

एक ही कोड अपने पुस्तकालय का संदर्भ देता है संकलन नहीं करता है के बाद आप परिवर्तन कर, इसलिए यह एक तोड़ने परिवर्तन है।

+5

अच्छा है! अंतर-भाषा ब्रेक कुछ सबसे कठिन हैं। –

+0

मैं वास्तव में संपत्तियों को लागू करने के तरीके से नफरत करता हूं।शुद्ध; मुझे तीन प्रकार के गुण होने का वास्तविक लाभ है, जिसमें से एक में संपत्ति के गेटर्स और सेटर्स को कुछ विशेषताओं के साथ विधियों के बजाय दो तरीकों को शामिल किया गया है, जो इंगित करता है कि, वाक्यविन्यास, डिबगिंग डिस्प्ले, क्रमबद्धता आदि के प्रयोजनों के लिए वे संपत्ति के रूप में माना जाना चाहिए? यदि 'प्रॉपर्टी ' प्रकार के पैरामीटर को स्वीकार करने के लिए नियमित रूप से संभव था, तो मैं गेटटर और सेटर को एक इकाई के रूप में एक साथ रखने के लिए कुछ वास्तविक लाभ देख सकता था, लेकिन ऐसा नहीं है। तो क्या फायदा है? – supercat

+0

@supercat यह ठीक है कि गुण .NET में कैसे काम करते हैं: आईएल कभी गुणों को कॉल नहीं करता है, केवल विधियों। गुण केवल मेटाटाडा में मौजूद हैं। तथ्य यह है कि गेटर और सेटर विधियां आसानी से सुलभ नहीं हैं भाषा डिजाइन का विषय है: वे सार्वजनिक विधियां हैं लेकिन अधिकांश भाषाओं द्वारा छिपी हुई हैं क्योंकि उनके पास 'स्पेशलनाम' विशेषता है। सी # स्पष्ट रूप से आपको इन विधियों को कॉल करने से रोकता है, मुझे नहीं पता। –

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