2016-06-16 19 views
10

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

नोट: "ब्रेक" से मेरा मतलब है कि यह सभी को संकलित करने में विफल रहता है या आईएल अवैध है। तो उदाहरण के लिए मैं इसे एक ब्रेकिंग चेंज नहीं मानूंगा:

// My.Library v1 
public struct MyStruct {} 

// My.Library v2 
public struct MyStruct { int _field; } 

// App code 
using My.Library; 
using System.Runtime.InteropServices; 

Console.WriteLine(Marshal.SizeOf<MyStruct>()); // before printed 1, now prints 4 

क्योंकि यह अभी भी चलता है।

+1

क्या आप अप्रबंधित कोड से बातचीत करने के लिए इंटरऑप सर्विसेज का उपयोग कर रहे हैं? यदि ऐसा है तो जवाब हाँ है, यह एक तोड़ने वाला परिवर्तन है। यदि नहीं, तो जवाब अधिक nuanced है। –

+0

क्षमा करें, मुझे आपके प्रश्न को समझ में नहीं आया ... आपने असेंबली को फिर से सम्मिलित किया, तो सब कुछ ठीक होना चाहिए? –

+0

जिटर बहुत सारे पाप छुपाता है। संरचना आकार बिल्ड समय, केवल रनटाइम पर कोई भूमिका नहीं निभाते हैं। एक अनिश्चित क्षेत्र होने के कारण आश्चर्यजनक हो सकता है। –

उत्तर

8

फ़ील्ड जोड़कर आकार बदलना कड़ाई से प्रबंधित कोड के लिए ठीक है।

फ़ील्ड जोड़ना गैर-ब्रेकिंग परिवर्तन है क्योंकि कोड नए प्रकार के साथ पुनः-जेआईटी-एड होगा और सभी आवंटन सही आकार का उपयोग करेंगे। चूंकि यह मान प्रकार है, इसलिए नए फ़ील्ड को वैसे भी खाली मूल्यों के साथ ठीक से शुरू किया जाएगा।

मौजूदा फ़ील्ड (ओं) या गुणों को हटाने/बदलने के प्रकार निश्चित रूप से परिवर्तन तोड़ रहे हैं।

वैल्यू प्रकारों को सील कर दिया गया है - इसलिए किसी भी अन्य पुस्तकालय उस प्रकार से प्राप्त नहीं हो सकते हैं - इसलिए कक्षाओं के विपरीत वे "इस व्युत्पन्न वर्ग ने नई वर्चुअल प्रॉपर्टी/इंटरफेस विधि को लागू नहीं किया" के साथ समस्याएं नहीं बना सकते हैं।

नोट: यदि किसी भी प्रकार के परिवर्तन को तोड़ने से इंटरऑप या आपके नियंत्रण के बाहर किसी अन्य प्रकार के बाइनरी धारावाहिकता के लिए उपयोग किया जाता है।

आईई। फ़ाइल में बाइनरी क्रमबद्धता के साथ बिंदुओं की एक सूची सहेजने के लिए किसी और ने MyLib.Point {int x;int y;} का उपयोग किया। यदि अब "माईलिब" क्रमबद्ध डेटा की तुलना में MyLib.Point पर एक नया फ़ील्ड जोड़ता है तो अब बाइनरी क्रमबद्धता के साथ पढ़ा नहीं जा सकता है। देशी इंटरऑप के साथ इसी तरह की समस्या।

3

हां, यदि आप एक नया क्षेत्र जोड़ते हैं, तो सख्ती से प्रबंधित कोड में भी, स्रोत कोड असंगतताएं संभवतः संभव हैं। अपने उदाहरण लें तो इस संस्करण 1 नहीं बल्कि संस्करण 2 के साथ संकलित:

MyStruct s; 
Console.WriteLine(s); 

कारण सी # एक struct स्थानीय अगर सभी क्षेत्रों मूल्यों सौंपा गया है इस्तेमाल किया जा करने की अनुमति देता है। संस्करण 1 में, कोई फ़ील्ड नहीं है इसलिए s "निश्चित रूप से असाइन किया गया" है। हालांकि यदि संस्करण 2 में कोई फ़ील्ड जोड़ा गया है, भले ही यह निजी है, तो यह अब संकलित नहीं होता है क्योंकि s अब निश्चित रूप से असाइन नहीं किया गया है।

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

जेरेड पार्सन्स के पास structs में निजी क्षेत्रों के विषय पर good blog post था जहां उन्होंने अन्य मामलों का विवरण दिया जहां निजी कार्यान्वयन विवरण बदलना खतरनाक होगा (असुरक्षित कोड के लिए) या तोड़ना।

+0

उपरोक्त। रास्ते में ब्लॉग पोस्ट के लिए धन्यवाद, एक दिलचस्प पढ़ा था। –

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