C # कक्षाओं को व्युत्पन्न करने की अनुमति नहीं देता है, लेकिन सभी ValueTypes ऑब्जेक्ट से प्राप्त होते हैं। यह भेद कहाँ बना है?
सीएलआर इसे कैसे संभालता है?
जवाबों:
C # कक्षाओं को प्राप्त करने की संरचना की अनुमति नहीं देता है
आपका कथन गलत है, इसलिए आपका भ्रम है। सी # करता structs वर्गों से प्राप्त करने के लिए अनुमति देते हैं। सभी संरचनाएं एक ही वर्ग से निकलती हैं, System.ValueType, जो System.Object से निकलती है। और सभी Enums System.Enum से निकलते हैं।
अद्यतन: कुछ (अब हटाए गए) टिप्पणियों में कुछ भ्रम है, जो स्पष्टीकरण को स्पष्ट करता है। मैं कुछ अतिरिक्त प्रश्न पूछूंगा:
क्या आधार प्रकार से संरचनाएं प्राप्त होती हैं?
पूरी तरह से हाँ। हम विनिर्देश के पहले पृष्ठ को पढ़कर इसे देख सकते हैं:
सभी सी # प्रकार, जैसे कि आदिम प्रकार जैसे कि इंट और डबल, एक ही रूट ऑब्जेक्ट प्रकार से विरासत में मिला।
अब, मैं ध्यान देता हूं कि विनिर्देश यहां मामला खत्म कर देता है। सूचक प्रकार ऑब्जेक्ट से प्राप्त नहीं होते हैं, और इंटरफ़ेस प्रकार और प्रकार पैरामीटर प्रकार के लिए व्युत्पत्ति संबंध इस स्केच संकेत से अधिक जटिल है। हालांकि, स्पष्ट रूप से यह मामला है कि सभी प्रकार के आधार आधार से निकलते हैं।
क्या अन्य तरीके हैं जो हम जानते हैं कि संरचनात्मक प्रकार आधार प्रकार से प्राप्त होते हैं?
ज़रूर। एक संरचना प्रकार ओवरराइड कर सकता है ToString
। ओवरराइडिंग क्या है, यदि इसके आधार प्रकार की आभासी विधि नहीं है? इसलिए इसका आधार प्रकार होना चाहिए। वह आधार प्रकार एक वर्ग है।
क्या मैं अपनी पसंद के वर्ग से उपयोगकर्ता-परिभाषित संरचना प्राप्त कर सकता हूं?
साभार सं। इसका मतलब यह नहीं है कि संरचना एक वर्ग से नहीं निकलती है । संरचनाएं एक वर्ग से निकलती हैं, और इस तरह उस वर्ग के विधर्मी सदस्यों को विरासत में मिलती हैं। वास्तव में, structs कर रहे हैं के लिए आवश्यक एक विशिष्ट वर्ग से प्राप्त करने के: Enums से प्राप्त करने के लिए आवश्यक हैं Enum
, structs से प्राप्त करने के लिए आवश्यक हैं ValueType
। क्योंकि इन की आवश्यकता होती है , सी # भाषा आपको कोड में व्युत्पत्ति संबंध को बताने से मना करती है ।
क्यों मना किया?
जब रिश्ते की आवश्यकता होती है , तो भाषा डिजाइनर के पास विकल्प होते हैं: (1) उपयोगकर्ता को आवश्यक झुकाव टाइप करने की आवश्यकता होती है, (2) इसे वैकल्पिक बनाते हैं, या (3) इसे मना करते हैं। प्रत्येक के पास पेशेवरों और विपक्ष हैं, और सी # भाषा डिजाइनरों ने प्रत्येक के विशिष्ट विवरण के आधार पर अलग-अलग रूप से चुना है।
उदाहरण के लिए, कास्ट फ़ील्ड्स को स्थिर होने की आवश्यकता होती है, लेकिन यह कहना मना है कि वे ऐसा कर रहे हैं क्योंकि ऐसा करना पहले, व्यर्थ क्रिया, और दूसरा है, इसका मतलब है कि गैर-स्थिर कॉस्ट फ़ील्ड हैं। लेकिन अतिभारित ऑपरेटरों को स्थिर के रूप में चिह्नित किया जाना आवश्यक है, भले ही डेवलपर के पास कोई विकल्प न हो; डेवलपर्स के लिए यह विश्वास करना बहुत आसान है कि ऑपरेटर अधिभार अन्यथा एक आवृत्ति विधि है। यह इस चिंता को दूर करता है कि एक उपयोगकर्ता को यह विश्वास हो सकता है कि "स्थिर" का अर्थ है कि, "आभासी" भी एक संभावना है।
इस मामले में, एक उपयोगकर्ता को यह कहने की आवश्यकता होती है कि ValueType से उनकी संरचना व्युत्पन्न होती है, जो केवल अत्यधिक क्रिया के समान है, और इसका अर्थ है कि यह संरचना किसी अन्य प्रकार से प्राप्त हो सकती है । इन दोनों समस्याओं को खत्म करने के लिए, C # इस कोड में यह बताना गैरकानूनी बनाता है कि एक आधार प्रकार से एक संरचना प्राप्त होती है, हालाँकि यह स्पष्ट रूप से होता है।
इसी तरह सभी प्रतिनिधि प्रकार से प्राप्त होते हैं MulticastDelegate
, लेकिन C # की आवश्यकता है कि आप ऐसा न कहें।
इसलिए, अब हमने यह स्थापित किया है कि C # सभी संरचनाएं एक वर्ग से निकलती हैं ।
एक वर्ग से विरासत और व्युत्पत्ति के बीच क्या संबंध है ?
कई लोग सी # में विरासत के रिश्ते से भ्रमित हैं। वंशानुक्रम संबंध काफी सीधा है: यदि कोई संरचना, वर्ग या प्रतिनिधि प्रकार D एक वर्ग प्रकार B से निकलता है तो B के विधर्मी सदस्य भी D के सदस्य हैं। यह उतना ही सरल है।
विरासत के संबंध में इसका क्या मतलब है जब हम कहते हैं कि एक मूल्य ValueType से निकलता है? बस यह कि ValueType के सभी धर्मार्थ सदस्य भी संरचना के सदस्य हैं। ToString
उदाहरण के लिए, इस तरह से उनके कार्यान्वयन को कैसे प्राप्त किया जाता है ; यह संरचना के आधार वर्ग से विरासत में मिला है।
सभी विधर्मी सदस्य? पक्का नहीं। क्या निजी सदस्य न्यायसंगत हैं?
हाँ। एक बेस क्लास के सभी निजी सदस्य भी व्युत्पन्न प्रकार के सदस्य हैं। यदि कॉल साइट सदस्य की पहुँच डोमेन में नहीं है, तो बेशक उन सदस्यों को कॉल करना अवैध है । सिर्फ इसलिए कि आपके पास कोई सदस्य नहीं है, इसका मतलब यह नहीं है कि आप इसका उपयोग कर सकते हैं!
अब हम मूल उत्तर के साथ जारी रखते हैं:
सीएलआर इसे कैसे संभालता है?
बहुत बढ़िया। :-)
एक मूल्य प्रकार एक मूल्य प्रकार बनाता है कि इसके उदाहरणों को मूल्य द्वारा कॉपी किया जाता है । एक संदर्भ प्रकार को संदर्भ प्रकार क्या बनाता है इसका उदाहरण संदर्भ द्वारा कॉपी किया जाता है । आपको कुछ विश्वास है कि मूल्य प्रकार और संदर्भ प्रकारों के बीच विरासत संबंध किसी भी तरह से विशेष और असामान्य है, लेकिन मुझे समझ में नहीं आता है कि यह विश्वास क्या है। इनहेरिटेंस का कोई लेना-देना नहीं है कि चीजों की नकल कैसे की जाती है।
इसे इस तरह देखो। मान लीजिए कि मैंने आपको निम्नलिखित तथ्य बताए:
दो तरह के बॉक्स होते हैं, लाल बॉक्स और ब्लू बॉक्स।
हर लाल डिब्बा खाली है।
ओ, वी और ई नामक तीन विशेष नीले बक्से हैं।
O किसी भी बॉक्स के अंदर नहीं है।
V, O के अंदर है।
E, V के अंदर है।
कोई दूसरा ब्लू बॉक्स V के अंदर नहीं है।
कोई ब्लू बॉक्स ई के अंदर नहीं है।
हर लाल बॉक्स V या E में है।
O के अलावा प्रत्येक ब्लू बॉक्स एक नीले बॉक्स के अंदर है।
नीले बॉक्स संदर्भ प्रकार हैं, लाल बॉक्स मूल्य प्रकार हैं, O सिस्टम है। विशेषण, V सिस्टम है। ValueType, E System.Enum है, और "अंदर" संबंध "से व्युत्पन्न" है।
यह नियमों का पूरी तरह से सुसंगत और सीधा सेट है जिसे आप आसानी से लागू कर सकते हैं, यदि आपके पास बहुत से कार्डबोर्ड और बहुत धैर्य है। चाहे बॉक्स लाल हो या नीला इसका अंदर क्या है, इससे कोई लेना-देना नहीं है; वास्तविक दुनिया में नीले बॉक्स के अंदर लाल बॉक्स लगाना पूरी तरह से संभव है। सीएलआर में, यह एक वैल्यू टाइप बनाने के लिए पूरी तरह से कानूनी है जो एक संदर्भ प्रकार से विरासत में मिलता है, इसलिए जब तक कि यह System.ValueType या System.Enum है।
तो चलिए आपका सवाल फिर से बताते हैं:
ValueTypes ऑब्जेक्ट (ReferenceType) से कैसे प्राप्त होते हैं और अभी भी ValueTypes होते हैं?
जैसा
यह कैसे संभव है कि हर लाल बॉक्स (मूल्य प्रकार) अंदर है (बॉक्स से निकलता है) O (System.Object), जो एक नीला बॉक्स (एक संदर्भ प्रकार) है और अभी भी एक लाल बॉक्स (एक मूल्य प्रकार) है?
जब आप इसे इस तरह वाक्यांश देते हैं, तो मुझे आशा है कि यह स्पष्ट है। बॉक्स V के अंदर लाल बॉक्स लगाने से कुछ भी नहीं है, जो बॉक्स O के अंदर है, जो नीला है। क्यों होगा?
अतिरिक्त अद्यतन:
जोन का मूल प्रश्न यह था कि यह कैसे संभव हैमान प्रकार एक संदर्भ प्रकार से प्राप्त होता है। मेरा मूल उत्तर वास्तव में किसी भी तंत्र की व्याख्या नहीं करता है जो सीएलआर इस तथ्य के लिए खाते का उपयोग करता है कि हमारे बीच दो चीजों के बीच एक व्युत्पत्ति संबंध है जो पूरी तरह से अलग प्रतिनिधित्व करते हैं - अर्थात्, चाहे संदर्भित डेटा में ऑब्जेक्ट हेडर हो, समन्वयन ब्लॉक, चाहे वह कचरा संग्रहण के उद्देश्यों के लिए अपना भंडारण हो, और इसी तरह। ये तंत्र जटिल हैं, एक उत्तर में समझाने के लिए बहुत जटिल हैं। सीएलआर प्रकार प्रणाली के नियम इसके कुछ हद तक सरल स्वाद की तुलना में थोड़ा अधिक जटिल हैं जो हम सी # में देखते हैं, जहां एक प्रकार के बॉक्सिंग और अनबॉक्स किए गए संस्करणों के बीच एक मजबूत अंतर नहीं है, उदाहरण के लिए। जेनेरिक की शुरूआत ने सीएलआर में अतिरिक्त जटिलता का एक बड़ा कारण भी जोड़ा।
लघु सुधार, C # केवल कुछ वर्गों से नहीं, किसी भी चीज़ से कस्टम व्युत्पन्न करने की अनुमति नहीं देता है। सभी एक संरचना ऐसा कर सकती है जो एक अंतरफलक को लागू करे जो व्युत्पत्ति से बहुत अलग हो।
मुझे लगता है कि इसका जवाब देने का सबसे अच्छा तरीका यह है कि ValueType
यह विशेष है। यह मूल रूप से सीएलआर प्रकार प्रणाली के सभी मूल्य प्रकारों के लिए आधार वर्ग है। यह जानना मुश्किल है कि "सीएलआर को कैसे संभालना है" इसका जवाब देना होगा क्योंकि यह केवल सीएलआर का एक नियम है।
ValueType
यह विशेष है, लेकिन यह स्पष्ट रूप से ध्यान देने योग्य है कि ValueType
वास्तव में एक संदर्भ प्रकार है।
यह CLR द्वारा बनाए गए कुछ हद तक कृत्रिम निर्माण है, ताकि सभी प्रकार के System.Object के रूप में व्यवहार किया जा सके।
मूल्य प्रकार के माध्यम से System.Object से निकाले जाते हैं System.ValueType है, जो है, जहां विशेष हैंडलिंग होता है (यानी: CLR हैंडल मुक्केबाजी / unboxing, किसी भी प्रकार ValueType से पाने के लिए आदि)।
आपका कथन गलत है, इसलिए आपका भ्रम है। C # कक्षाओं से व्युत्पन्न करने की अनुमति देता है। सभी संरचनाएं एक ही वर्ग से निकलती हैं, System.ValueType
तो चलिए इसे आजमाते हैं:
struct MyStruct : System.ValueType
{
}
यह भी संकलन नहीं होगा। कंपाइलर आपको याद दिलाएगा कि "टाइप लिस्ट 'System.ValueType' इंटरफ़ेस सूची में इंटरफ़ेस नहीं है"।
जब एक संरचना है जो डिकम्पाइल Int32, आप पाएंगे:
सार्वजनिक संरचना Int32: IComparable, IFormattable, IConvertible {}, यह उल्लेख नहीं करने के लिए कि यह System.ValueType से लिया गया है। लेकिन ऑब्जेक्ट ब्राउज़र में, आपको लगता है कि Int32 System.ValueType से इनहेरिट करता है।
तो ये सभी मुझे विश्वास करने के लिए प्रेरित करते हैं:
मुझे लगता है कि इसका जवाब देने का सबसे अच्छा तरीका यह है कि ValueType विशेष है। यह मूल रूप से सीएलआर प्रकार प्रणाली के सभी मूल्य प्रकारों के लिए आधार वर्ग है। यह जानना मुश्किल है कि "सीएलआर को कैसे संभालना है" इसका जवाब देना होगा क्योंकि यह केवल सीएलआर का एक नियम है।
ValueType
, तो यह दो प्रकार की वस्तुओं को परिभाषित करने के लिए उपयोग करता है: एक ढेर वस्तु प्रकार एक संदर्भ प्रकार की तरह व्यवहार करता है, और एक भंडारण स्थान प्रकार जो प्रभावी रूप से टाइप-इनहेरिटेंस सिस्टम के बाहर होता है। क्योंकि उन दो प्रकार की चीजों का उपयोग परस्पर-अनन्य संदर्भों में किया जाता है, इसलिए दोनों के लिए एक ही प्रकार के विवरणकों का उपयोग किया जा सकता है। सीएलआर स्तर पर, एक संरचना को उस वर्ग के रूप में परिभाषित किया जाता है जिसके माता-पिता हैं System.ValueType
, लेकिन C # ...
System.ValueType
) से विरासत में प्राप्त कर सकते हैं , और वर्गों को यह निर्दिष्ट करने से मना करते हैं कि वे विरासत में मिले हैं System.ValueType
क्योंकि किसी भी वर्ग को जिस तरह से घोषित किया गया था, वह मूल्य प्रकार की तरह व्यवहार करेगा।
एक बॉक्सिंग मूल्य प्रकार प्रभावी रूप से एक संदर्भ प्रकार है (यह एक की तरह चलता है और एक की तरह चलता है, इसलिए प्रभावी रूप से यह एक है)। मेरा सुझाव है कि ValueType वास्तव में आधार प्रकारों का प्रकार नहीं है, बल्कि आधार संदर्भ प्रकार है, जिस पर ऑब्जेक्ट प्रकार टाइप करने पर मूल्य प्रकार परिवर्तित किए जा सकते हैं। गैर-बॉक्सिंग मूल्य प्रकार स्वयं वस्तु पदानुक्रम के बाहर हैं।
सभी उत्तरों में से, @ सुपरकैट का उत्तर वास्तविक उत्तर के सबसे करीब आता है। चूँकि अन्य उत्तर वास्तव में प्रश्न का उत्तर नहीं देते हैं, और बिलकुल गलत दावे करते हैं (उदाहरण के लिए कि मूल्य प्रकार कुछ भी प्राप्त होता है), मैंने प्रश्न का उत्तर देने का निर्णय लिया।
यह उत्तर मेरी अपनी रिवर्स इंजीनियरिंग और सीएलआई विनिर्देश पर आधारित है।
struct
और class
C # कीवर्ड हैं। जहां तक सीएलआई का संबंध है, सभी प्रकार (वर्ग, इंटरफेस, संरचना, आदि) को कक्षा की परिभाषाओं द्वारा परिभाषित किया गया है।
उदाहरण के लिए, एक ऑब्जेक्ट प्रकार (C # के रूप में जाना जाता है class
) को निम्नानुसार परिभाषित किया गया है:
.class MyClass
{
}
एक इंटरफ़ेस interface
शब्दार्थ विशेषता के साथ एक वर्ग परिभाषा द्वारा परिभाषित किया गया है :
.class interface MyInterface
{
}
कारण है कि संरचना से विरासत में मिल सकता है System.ValueType
और अभी भी मूल्य प्रकार हो सकता है, क्योंकि .. वे नहीं है।
मूल्य प्रकार सरल डेटा संरचनाएं हैं। मान प्रकार कुछ से विरासत में नहीं मिलते हैं और वे इंटरफेस को लागू नहीं कर सकते हैं । मूल्य प्रकार किसी भी प्रकार के उपप्रकार नहीं हैं, और उनके पास किसी भी प्रकार की जानकारी नहीं है। एक मान प्रकार के स्मृति पते को देखते हुए, यह पहचानना संभव नहीं है कि किसी संदर्भ प्रकार के विपरीत मान जो किसी छिपे हुए क्षेत्र में टाइप जानकारी रखता है, का प्रतिनिधित्व करता है।
यदि हम निम्नलिखित C # संरचना की कल्पना करते हैं:
namespace MyNamespace
{
struct MyValueType : ICloneable
{
public int A;
public int B;
public int C;
public object Clone()
{
// body omitted
}
}
}
निम्नलिखित उस संरचना की IL वर्ग परिभाषा है:
.class MyNamespace.MyValueType extends [mscorlib]System.ValueType implements [mscorlib]System.ICloneable
{
.field public int32 A;
.field public int32 B;
.field public int32 C;
.method public final hidebysig newslot virtual instance object Clone() cil managed
{
// body omitted
}
}
तो यहां क्या हो रहा है? यह स्पष्ट रूप से फैली हुई है System.ValueType
, जो एक वस्तु / संदर्भ प्रकार है, और लागू होती है System.ICloneable
।
स्पष्टीकरण यह है कि जब एक वर्ग परिभाषा का विस्तार होता है तो System.ValueType
यह वास्तव में 2 चीजों को परिभाषित करता है: एक मूल्य प्रकार, और मूल्य प्रकार का संबंधित बॉक्सिंग प्रकार। वर्ग परिभाषा के सदस्य मूल्य प्रकार और संबंधित बॉक्सिंग प्रकार दोनों के लिए प्रतिनिधित्व को परिभाषित करते हैं। यह वह मूल्य प्रकार नहीं है जो विस्तार और लागू होता है, यह उसी प्रकार का बॉक्सिंग प्रकार है जो करता है। extends
और implements
कीवर्ड को केवल बॉक्स्ड प्रकार के लिए लागू।
स्पष्ट करने के लिए, ऊपर दी गई कक्षा परिभाषा 2 चीजें करती है:
System.ValueType
और कार्यान्वित करना System.ICloneable
।यह भी ध्यान दें, कि किसी भी वर्ग की परिभाषा का विस्तार System.ValueType
भी आंतरिक रूप से सील है, चाहे वह sealed
कीवर्ड निर्दिष्ट किया गया हो या नहीं।
चूंकि मूल्य प्रकार केवल सरल संरचनाएं हैं, इनहेरिट नहीं करते हैं, लागू नहीं करते हैं और बहुरूपता का समर्थन नहीं करते हैं, इसलिए उन्हें बाकी प्रकार की प्रणाली के साथ उपयोग नहीं किया जा सकता है। इसके चारों ओर काम करने के लिए, मूल्य प्रकार के शीर्ष पर, सीएलआर एक ही संदर्भ प्रकार को उसी फ़ील्ड के साथ भी परिभाषित करता है, जिसे बॉक्स प्रकार कहा जाता है। तो जबकि एक मूल्य प्रकार के तरीकों के आसपास पारित नहीं किया जा सकता है object
, इसकी इसी बॉक्सिंग प्रकार कर सकते हैं ।
अब, यदि आप C # जैसे किसी विधि को परिभाषित करने वाले थे
public static void BlaBla(MyNamespace.MyValueType x)
,
तुम्हें पता है कि विधि मूल्य प्रकार ले जाएगा MyNamespace.MyValueType
।
ऊपर, हमने पाया कि struct
C # में कीवर्ड से मिलने वाली वर्ग परिभाषा वास्तव में एक मूल्य प्रकार और एक वस्तु प्रकार दोनों को परिभाषित करती है। हम केवल परिभाषित मूल्य प्रकार का उल्लेख कर सकते हैं, हालांकि। भले ही सीएलआई विनिर्देश बताता है कि बाधा कीवर्ड boxed
का उपयोग किसी प्रकार के बॉक्सिंग संस्करण को संदर्भित करने के लिए किया जा सकता है, यह कीवर्ड मौजूद नहीं है (ECMA-335, II.13.1 संदर्भ मूल्य प्रकार देखें)। लेकिन कल्पना करता है कि यह एक पल के लिए करता है।
आईएल में प्रकारों का संदर्भ देते समय, कुछ बाधाओं का समर्थन किया जाता है, जिनमें से हैं class
और valuetype
। यदि हम उपयोग valuetype MyNamespace.MyType
करते हैं तो हम MyNamespace.MyType नामक मान प्रकार वर्ग परिभाषा निर्दिष्ट कर रहे हैं। इसी तरह, हम class MyNamespace.MyType
MyNamespace.MyType नामक ऑब्जेक्ट प्रकार वर्ग परिभाषा को निर्दिष्ट करने के लिए उपयोग कर सकते हैं । जिसका अर्थ है कि IL में आपके पास एक ही नाम के साथ एक मान प्रकार (संरचना) और एक ऑब्जेक्ट प्रकार (वर्ग) हो सकता है और फिर भी उन्हें अलग कर सकता है। अब, यदि boxed
CLI विनिर्देश द्वारा उल्लिखित कीवर्ड वास्तव में लागू किया गया था, तो हम boxed MyNamespace.MyType
MyNamespace.MyType नामक मूल्य प्रकार वर्ग परिभाषा के बॉक्सिंग प्रकार को निर्दिष्ट करने के लिए उपयोग करने में सक्षम होंगे ।
तो, .method static void Print(valuetype MyNamespace.MyType test) cil managed
मूल्य प्रकार वर्ग परिभाषा द्वारा परिभाषित मूल्य प्रकार लेता है MyNamespace.MyType
, जिसका नाम है ,
जबकि .method static void Print(class MyNamespace.MyType test) cil managed
ऑब्जेक्ट प्रकार वर्ग परिभाषा द्वारा परिभाषित ऑब्जेक्ट प्रकार नाम लेता है MyNamespace.MyType
।
इसी तरह यदि boxed
कोई कीवर्ड था, .method static void Print(boxed MyNamespace.MyType test) cil managed
तो नामांकित वर्ग परिभाषा द्वारा परिभाषित मूल्य प्रकार का बॉक्सिंग प्रकार ले जाएगा MyNamespace.MyType
।
फिर आप किसी भी अन्य ऑब्जेक्ट प्रकार की तरह बॉक्सिंग प्रकार को तुरंत सक्षम कर सकते हैं और इसे किसी भी विधि के पास पास कर सकते हैं System.ValueType
, जो एक तर्क के रूप में object
या boxed MyNamespace.MyValueType
एक तर्क के रूप में लेता है , और यह सभी अन्य उद्देश्यों और उद्देश्यों के लिए, किसी अन्य संदर्भ प्रकार की तरह काम करेगा। यह एक मूल्य प्रकार नहीं है, लेकिन मूल्य के प्रकार के संबंधित बॉक्सिंग प्रकार है।
तो, सारांश में, और प्रश्न का उत्तर देने के लिए:
मान प्रकार संदर्भ प्रकार नहीं हैं और किसी अन्य प्रकार से इनहेरिट नहीं करते हैंSystem.ValueType
, और वे इंटरफ़ेस को लागू नहीं कर सकते हैं । संबंधित बॉक्स प्रकार जो भी परिभाषित किए गए हैं वे इनहेरिट करते हैंSystem.ValueType
और इंटरफेस को लागू कर सकते हैं ।
एक .class
परिभाषा परिस्थिति के आधार पर विभिन्न चीजों को परिभाषित करती है।
interface
शब्दार्थ विशेषता निर्दिष्ट की जाती है, तो वर्ग परिभाषा एक अंतरफलक को परिभाषित करती है।interface
शब्दार्थ गुण निर्दिष्ट नहीं है, और परिभाषा विस्तार नहीं करती है System.ValueType
, तो वर्ग परिभाषा एक वस्तु प्रकार (वर्ग) को परिभाषित करती है।interface
सिमेंटिक विशेषता निर्दिष्ट नहीं है, और परिभाषा का विस्तार होता है System.ValueType
, तो वर्ग परिभाषा एक मूल्य प्रकार और उसके संबंधित बॉक्सिंग प्रकार (संरचना) को परिभाषित करती है ।यह खंड 32-बिट प्रक्रिया मानता है
जैसा कि पहले ही उल्लेख किया गया है, मूल्य प्रकारों में प्रकार की जानकारी नहीं होती है, और इस प्रकार यह पहचानना संभव नहीं है कि मूल्य प्रकार इसकी स्मृति स्थान से क्या दर्शाता है। एक संरचना एक साधारण डेटा प्रकार का वर्णन करती है, और इसमें परिभाषित किए गए फ़ील्ड शामिल हैं:
public struct MyStruct
{
public int A;
public short B;
public int C;
}
यदि हम कल्पना करते हैं कि MyStruct का एक उदाहरण 0x1000 पते पर आवंटित किया गया था, तो यह मेमोरी लेआउट है:
0x1000: int A;
0x1004: short B;
0x1006: 2 byte padding
0x1008: int C;
अनुक्रमिक लेआउट के लिए डिफ़ॉल्ट डिफ़ॉल्ट। फ़ील्ड्स अपने स्वयं के आकार की सीमाओं पर गठबंधन किए जाते हैं। इसे संतुष्ट करने के लिए पैडिंग को जोड़ा जाता है।
यदि हम एक कक्षा को ठीक उसी तरह परिभाषित करते हैं, जैसे:
public class MyClass
{
public int A;
public short B;
public int C;
}
उसी पते की कल्पना करते हुए, मेमोरी लेआउट इस प्रकार है:
0x1000: Pointer to object header
0x1004: int A;
0x1008: int C;
0x100C: short B;
0x100E: 2 byte padding
0x1010: 4 bytes extra
कक्षाएं स्वचालित लेआउट के लिए डिफ़ॉल्ट होती हैं, और जेआईटी कंपाइलर उन्हें सबसे इष्टतम क्रम में व्यवस्थित करेंगे। फ़ील्ड्स अपने स्वयं के आकार की सीमाओं पर गठबंधन किए जाते हैं। इसे संतुष्ट करने के लिए पैडिंग को जोड़ा जाता है। मुझे यकीन नहीं है कि क्यों, लेकिन हर वर्ग के अंत में एक अतिरिक्त 4 बाइट्स होती हैं।
ऑफसेट 0 में ऑब्जेक्ट हेडर का पता होता है, जिसमें टाइप इंफॉर्मेशन, वर्चुअल मेथड टेबल आदि होते हैं। यह रनटाइम को यह पहचानने की अनुमति देता है कि किसी एड्रेस पर मौजूद डेटा वैल्यू टाइप के विपरीत क्या दर्शाता है।
इस प्रकार, मूल्य प्रकार विरासत, इंटरफेस और न ही बहुरूपता का समर्थन नहीं करते हैं।
मान प्रकार में वर्चुअल विधि तालिकाएँ नहीं होती हैं, और इस प्रकार बहुरूपता का समर्थन नहीं करते हैं। हालाँकि , उनके संबंधित बॉक्सिंग प्रकार करता है ।
यदि आप एक struct का एक उदाहरण है और की तरह एक आभासी विधि कॉल करने का प्रयास करते हैं ToString()
पर परिभाषित System.Object
, क्रम struct बॉक्स करने के है।
MyStruct myStruct = new MyStruct();
Console.WriteLine(myStruct.ToString()); // ToString() call causes boxing of MyStruct.
हालाँकि, यदि संरचना ओवरराइड होती है, ToString()
तो कॉल स्टेटिक रूप से बाध्य हो जाएगा और रनटाइम MyStruct.ToString()
बॉक्सिंग के बिना और किसी भी वर्चुअल मेथड टेबल में देखे बिना कॉल करेगा (स्ट्रक्चर्स के पास कोई नहीं है)। इस कारण से, यह ToString()
कॉल को इनलाइन करने में भी सक्षम है ।
यदि संरचना ओवरराइड होती है ToString()
और बॉक्सिंग होती है, तो वर्चुअल विधि तालिका का उपयोग करके कॉल को हल किया जाएगा।
System.ValueType myStruct = new MyStruct(); // Creates a new instance of the boxed type of MyStruct.
Console.WriteLine(myStruct.ToString()); // ToString() is now called through the virtual method table.
हालांकि, याद रखें कि ToString()
संरचना में परिभाषित किया गया है, और इस प्रकार संरचना मूल्य पर संचालित होता है, इसलिए यह एक मूल्य प्रकार की अपेक्षा करता है। किसी अन्य वर्ग की तरह, बॉक्सिंग प्रकार में ऑब्जेक्ट हेडर होता है। अगर ToString()
विधि struct पर परिभाषित में बॉक्स्ड प्रकार के साथ सीधे बुलाया गया था this
सूचक, जब पहुँच क्षेत्र की कोशिश A
में MyStruct
है, यह ऑफसेट 0, जो बॉक्स्ड प्रकार में वस्तु हैडर सूचक होगा पहुंच जाएगा। तो बॉक्सिंग प्रकार में एक छिपी हुई विधि है जो वास्तविक ओवरराइडिंग करती है ToString()
। यह छिपा हुआ तरीका अनबॉक्स (केवल unbox
आईएल इंस्ट्रक्शन की तरह पता गणना ) बॉक्सिंग प्रकार फिर सांख्यिकीय ToString()
रूप से संरचना पर परिभाषित कहता है ।
इसी तरह, बॉक्सिंग प्रकार में प्रत्येक कार्यान्वित इंटरफ़ेस विधि के लिए एक छिपी हुई विधि होती है जो समान अनबॉक्सिंग करती है और फिर संरचनात्मक रूप से परिभाषित विधि को कॉल करती है।
I.8.2.4 प्रत्येक मूल्य प्रकार के लिए, CTS एक संबंधित संदर्भ प्रकार को परिभाषित करता है जिसे बॉक्सिंग प्रकार कहा जाता है। रिवर्स सच नहीं है: सामान्य तौर पर, संदर्भ प्रकारों में एक समान मूल्य प्रकार नहीं होता है। एक बॉक्सिंग प्रकार (एक बॉक्सिंग मूल्य) के मूल्य का प्रतिनिधित्व एक ऐसा स्थान है जहां मूल्य प्रकार के मूल्य को संग्रहीत किया जा सकता है। एक बॉक्सिंग प्रकार एक ऑब्जेक्ट प्रकार है और एक बॉक्सिंग मूल्य एक ऑब्जेक्ट है।
I.8.9.7 वर्ग परिभाषा द्वारा परिभाषित सभी प्रकार वस्तु प्रकार नहीं हैं (देखें .2I.8.2.3); विशेष रूप से, मूल्य प्रकार ऑब्जेक्ट प्रकार नहीं होते हैं, लेकिन उन्हें एक वर्ग परिभाषा का उपयोग करके परिभाषित किया जाता है। मान प्रकार के लिए एक वर्ग परिभाषा दोनों (अनबॉक्स) मान प्रकार और संबंधित बॉक्सिंग प्रकार (.4I.8.8.4 देखें) को परिभाषित करती है। वर्ग परिभाषा के सदस्य दोनों के प्रतिनिधित्व को परिभाषित करते हैं।
II.10.1.3 प्रकार के शब्दार्थ गुण निर्दिष्ट करते हैं कि क्या कोई इंटरफ़ेस, वर्ग या मान प्रकार परिभाषित किया जाएगा। इंटरफ़ेस विशेषता एक इंटरफ़ेस निर्दिष्ट करती है। यदि यह विशेषता मौजूद नहीं है और परिभाषा फैली हुई है (प्रत्यक्ष या अप्रत्यक्ष रूप से) System.ValueType, और परिभाषा System.Enum के लिए नहीं है, तो एक मान प्रकार परिभाषित किया जाएगा (.1II.13)। अन्यथा, एक वर्ग परिभाषित किया जाएगा (.11II.11)।
I.8.9.10 उनके अनबॉक्स्ड फॉर्म में मूल्य प्रकार किसी भी प्रकार से प्राप्त नहीं होते हैं। बॉक्स किए गए मूल्य प्रकार सीधे System.ValueType से इनहेरिट करेंगे जब तक कि वे एन्यूमरेशन नहीं होते हैं, इस स्थिति में, वे System.Enum से वारिस होंगे। बॉक्सिंग मूल्य प्रकारों को सील किया जाएगा।
II.13 अनबॉक्स किए गए मान प्रकारों को किसी अन्य प्रकार के उपप्रकार नहीं माना जाता है और यह अनबॉक्स किए गए मान प्रकारों पर आइंस्टीन निर्देश (विभाजन III देखें) का उपयोग करने के लिए मान्य नहीं है। आइंस्टीन निर्देश का उपयोग बॉक्सिंग मूल्य प्रकारों के लिए किया जा सकता है, हालांकि।
I.8.9.10 एक मान प्रकार इनहेरिट नहीं करता है; वर्ग परिभाषा में निर्दिष्ट आधार प्रकार, बॉक्स प्रकार के आधार प्रकार को परिभाषित करता है।
I.8.9.7 मान प्रकार इंटरफ़ेस अनुबंधों का समर्थन नहीं करते हैं, लेकिन उनके संबद्ध बॉक्सिंग प्रकार करते हैं।
II.13 मान प्रकार शून्य या अधिक इंटरफ़ेस लागू करेंगे, लेकिन इसका अर्थ केवल उनके बॉक्सिंग रूप में है (.1II.13.3)।
I.8.2.4 इंटरफेस और वंशानुक्रम केवल संदर्भ प्रकारों पर परिभाषित किए गए हैं। इस प्रकार, जबकि एक मूल्य प्रकार की परिभाषा (§I.8.9.7) उन दोनों इंटरफेस को निर्दिष्ट कर सकती है जिन्हें मूल्य प्रकार और वर्ग (System.ValueType या System.Enum) से लागू किया जा सकता है, जहां से यह विरासत में मिलता है, ये केवल बॉक्सिंग मूल्यों पर लागू होते हैं ।
II.13.1 एक वैल्यू टाइप का अनबॉक्स्ड फॉर्म एक प्रकार के रेफरेंस के बाद वैल्यूएटाइप कीवर्ड का उपयोग करके संदर्भित किया जाएगा। एक प्रकार के संदर्भ के बाद एक मूल्य प्रकार के बॉक्सिंग फार्म का संदर्भ बॉक्सिंग कीवर्ड का उपयोग करके किया जाएगा।
नोट: यहां विनिर्देश गलत है, कोई boxed
कीवर्ड नहीं है ।
मुझे लगता है कि मूल्य प्रकार विरासत में कैसे लगते हैं, इस भ्रम का एक हिस्सा है, इस तथ्य से उपजा है कि सी # बॉक्सिंग और अनबॉक्सिंग करने के लिए कास्टिंग सिंटैक्स का उपयोग करता है, जिससे ऐसा लगता है कि आप कलाकारों का प्रदर्शन कर रहे हैं, जो वास्तव में मामला नहीं है (हालांकि, CLR एक InvalidCastException को फेंक देगा यदि गलत प्रकार को अनबॉक्स करने का प्रयास किया जा रहा है)।
(object)myStruct
C # में मूल्य प्रकार के बॉक्सिंग प्रकार का एक नया उदाहरण बनाता है; यह किसी भी जाति का प्रदर्शन नहीं करता है। इसी तरह, (MyStruct)obj
सी # में एक बॉक्सिंग प्रकार को अनबॉक्स किया जाता है, मान भाग को कॉपी करके; यह किसी भी जाति का प्रदर्शन नहीं करता है।
System.ValueType
CLR प्रकार प्रणाली में काले जादू के प्रकार का परिणाम ।