Int [] एक संदर्भ प्रकार या एक मूल्य प्रकार है?


124

मुझे पता है कि एक इंट एक वैल्यू टाइप है, लेकिन वैल्यू टाइप के एरेज़ क्या हैं? संदर्भ प्रकार? मूल्य प्रकार? मैं किसी फ़ंक्शन को चेक करने के लिए किसी सरणी को पास करना चाहता हूं। क्या मुझे सिर्फ सरणी पास करनी चाहिए, क्योंकि यह सिर्फ इसके संदर्भ को पारित करेगा, या मुझे इसे रेफ के रूप में पारित करना चाहिए?


11
भविष्य में, आप जाँच सकते हैं कि क्या कोई चीज संदर्भ द्वारा या मान को चर बनाकर पारित की जाती है, उस चर को उस चर में बदल देती है जो उस चर को बदल देता है, और जाँच करता है कि उस चर का मान उस पद्धति से चलने के बाद क्या है। यदि यह समान है, तो इसका मूल्य, अलग-अलग, संदर्भ द्वारा पारित किया गया है।

11
@ darkassassin93: संदर्भ या मूल्य से गुजरना इस बात से असंबंधित है कि क्या कोई संदर्भ प्रकार या मान प्रकार है। (मूल्य प्रकारों को संदर्भ द्वारा पारित किया जा सकता है और संदर्भ प्रकारों को मूल्य से पारित किया जा सकता है।)
ल्यूक

2
ज्यादातर मामलों में अगर आप एक क्षेत्र या चर के अंदर [अशक्त] स्टोर कर सकते हैं तो आप मान सकते हैं कि यह एक रेफ प्रकार है। अपवाद निश्चित रूप से अशक्त प्रकार हैं (अशक्त <int> या int?) साथ ही तार।
नोएल विडमर

3
@ NoëlWidmer स्ट्रिंग्स अपवाद नहीं हैं: वे प्रकार हैं।
आर्थर कास्त्रो

2
@ArthurCastro 50% करने के लिए Argree: तार वर्ग से विरासत में मिला है कि वे संदर्भ प्रकार हैं। हालाँकि उनकी समानता संदर्भ के बजाय पहचान (मूल्य तुलना) पर आधारित है और उनके पास का व्यवहार मूल्य प्रकारों के व्यवहार से मेल खाने के लिए अधिक महत्वपूर्ण है। मूल रूप से वे परिभाषा के अनुसार संदर्भ प्रकार हैं, लेकिन कार्यान्वयन द्वारा मूल्य प्रकार की तरह अधिक व्यवहार करते हैं।
नोएल विडमर

जवाबों:


201

एरेस वे तंत्र हैं जो आपको एक संग्रह के रूप में कई वस्तुओं का इलाज करने की अनुमति देते हैं। Microsoft® .NET सामान्य भाषा रनटाइम (CLR) एकल-आयामी सरणियों, बहुआयामी सरणियों और दांतेदार सरणियों (सरणियों के सरणियों) का समर्थन करता है। सभी सरणी प्रकार अंतर्निहित रूप से System.Array से प्राप्त होते हैं, जो स्वयं System.Object से लिया गया है। इसका मतलब है कि सभी सरणियाँ हमेशा संदर्भ प्रकार होती हैं जो प्रबंधित हीप पर आवंटित की जाती हैं, और आपके ऐप के चर में सरणी का संदर्भ होता है न कि सरणी का।

https://msdn.microsoft.com/en-us/library/bb985948.aspx


54
मान प्रकार System.ValueType से विरासत में मिला है जो स्वयं System.Object से विरासत में मिला है। तो सिर्फ इसलिए कि Array System.Object से निकला है, इसका मतलब यह नहीं है कि यह एक संदर्भ प्रकार है। सिस्टम क्या बनाता है। एक संदर्भ प्रकार के बारे में यह है कि यह उदाहरणों को संदर्भ द्वारा कॉपी किया जाता है। IOW, इस तथ्य पर ध्यान केंद्रित करें कि System.Array एक वर्ग है। यही कारण है कि यह एक संदर्भ प्रकार बनाता है।
पी। ब्रायन। मैके

8
<nitpick> मुझे पता है कि यह दस्तावेज की तरह लग रहा है कि System.Array System.Object से प्राप्त होता है जो इसे एक संदर्भ प्रकार बनाता है। हालाँकि यह सच नहीं हो सकता है कि System.Object से निकला कोई भी प्रकार एक संदर्भ प्रकार है, इस नियम का एकमात्र अपवाद System.ValueType है, जिसे संकलक द्वारा अलग तरीके से व्यवहार किया जाता है। </ nitpick>
Yannue Motton

ऊपर का लिंक टूटा हुआ है। यहाँ एक और msdn लिंक है जो System.Array की विरासत पदानुक्रम दिखाता है: msdn.microsoft.com/de-de/library/system.array(v=vs.110).aspx
MUGNN

कुछ भी जो System.Object से निकलता है, एक संदर्भ प्रकार है, UNLESS यह भी System.ValueType से निकलता है। @ P.Brian.Mackey सिर्फ इसलिए कि एक प्रकार एक वर्ग है इसका मतलब यह नहीं है कि यह एक संदर्भ प्रकार है, क्योंकि पर्दे के पीछे, स्ट्रक्चर्स केवल वे वर्ग हैं जो System.ValueType से प्राप्त होते हैं।
डेविड क्लेम्फनर 22

31

संदर्भ प्रकार बनाम मान प्रकार के लिए सबसे सरल परीक्षण यह है कि संदर्भ प्रकार हो सकते हैं null, लेकिन मूल्य प्रकार नहीं हो सकते।


46
... अशक्त मान प्रकारों को छोड़कर, जो अशक्त हैं (आप मान को अशक्त करने के लिए सेट कर सकते हैं, जिसका अर्थ है अशक्त संदर्भ के बजाय प्रकार के लिए अशक्त मान ) और अभी भी मूल्य प्रकार हैं।
जॉन स्कीट

1
ऐसा करने के बारे में कभी नहीं सोचा था कि जब वे मूल्य प्रकार हैं या नहीं समझने की कोशिश कर रहे हैं! महान विचार।
ईटलीसियम


6

पहले मैं आपको बताना चाहता हूं कि ऐरे एक संदर्भ प्रकार है। क्यों? मैं समझाता हूं कि एक उदाहरण यहां पर फेंक दूंगा।

उदाहरण:

int val = 0; // this is a value type ok
int[] val1 = new int[20] // this is a reference type because space required to store 20 integer value that make array allocated on the heap.

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

स्टैक में संग्रहीत मान प्रकार और हीप में संग्रहीत संदर्भ प्रकार

आप फ़ंक्शन या रेफरी का उपयोग करके फ़ंक्शन को पास कर सकते हैं। केवल प्रारंभिक तरीके अलग हैं।

अधिक..


3

सत्यापित करने के लिए परीक्षण करें कि क्या यह एक संदर्भ या मूल्य प्रकार है:

// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************

आप इसे ऑनलाइन टेस्ट कर सकते हैं: https://dotnetfiddle.net/UWFP45


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

पूर्वाभास हो। एक बार C # 8 जारी होने के बाद, यह भी विफल हो जाएगा यदि आप अशक्त संदर्भ प्रकार की सुविधा का उपयोग कर रहे हैं क्योंकि गैर-अशक्त संदर्भ प्रकार या तो शून्य स्वीकार नहीं कर सकते।
मार्क ए। डोनोहे

2

सरणी अपने आप में एक संदर्भ प्रकार है। सरणी डेटा प्रकार द्वारा निर्धारित किए गए मान के मान उस मान या संदर्भ प्रकार हैं। आपके उदाहरण में, सरणी एक संदर्भ प्रकार है और मान मान प्रकार हैं।

सभी एकल-आयाम सरणियों को स्पष्ट रूप से लागू किया जाता है IList<T>, जहां <T>सरणी का डेटा प्रकार है। आप उस इंटरफ़ेस का उपयोग अपने विधि पैरामीटर के डेटा प्रकार के बजाय कर सकते हैं। आप IEnumerable<T>डेटा प्रकार के लिए भी उपयोग कर सकते हैं । या तो मामले में (या यहां तक ​​कि अगर आप सिर्फ उपयोग करते हैं int[]) आपको इसे एक refपैरामीटर के रूप में स्पष्ट रूप से पारित करने की आवश्यकता नहीं होनी चाहिए ।


0

// सरणी का संदर्भ मूल्य द्वारा पारित किया गया है। यह भ्रम का स्रोत है :-) ...

        int[] test = { 1, 2, 3, 4 };

        modifContenuSansRef(test);
        Console.WriteLine(test[0]); // OK --> 99 le contenu du tableau est modifié

        modifTailleSansRef(test);
        Console.WriteLine(test.Length); // KO --> 4 La taille n'est pas modifiée

    }

    static void modifContenuSansRef(int[] t)
    {
        t[0] = 99;
    }

    static void modifTailleSansRef(int[] t)
    {
        Array.Resize(ref t, 8);
    }

0

Arrays हमेशा संदर्भ प्रकार होते हैं। इससे कोई फर्क नहीं पड़ता कि सरणी में मान प्रकार होगा जैसे int या संदर्भ प्रकार जैसे string। जब आप उदाहरण के लिए सरणी घोषित करते हैं

int[] integers=new int[10];

पूर्णांक चर में केवल उसी सरणी का संदर्भ होता है जो ढेर में रहता है।

इसके अलावा कई लोगों का उल्लेख है कि आप संदर्भ प्रकार से अलग-अलग मान टाइप कर सकते हैं बस इस बात पर निर्भर करते हैं कि क्या परिवर्तनशील चर शून्य हो सकता है या नहीं। मैं यह उल्लेख करना चाहूंगा कि c # वर्तमान में मूल्य प्रकार भी शून्य हो सकते हैं

उदाहरण के लिए

int? integer=null

और यह पहचानने का अच्छा तरीका नहीं है कि प्रकार संदर्भ या मूल्य है केवल इस तथ्य पर निर्भर करता है कि चर शून्य हो सकता है या नहीं।


-2

बस एक अंतर्दृष्टि:

उदाहरण के लिए, intएक पूर्णांक का int[]प्रतिनिधित्व करता है , पूर्णांक की एक सरणी का प्रतिनिधित्व करता है।

विशिष्ट आयामों के साथ सरणी को आरंभ करने के लिए, आप newकीवर्ड का उपयोग कर सकते हैं , प्रकार नाम के बाद वर्ग कोष्ठक में आकार देते हुए:

//create a new array of 32 ints.
int[] integers = new int[32];

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

int[] copy = integers;

यह एक ही सरणी को संदर्भित करने के लिए पूरी चर प्रति असाइन करेगा, यह एक नया सरणी नहीं बनाएगा।

C # का सरणी सिंटैक्स लचीला है, यह आपको ऐरे को ऐंसे बिना भी घोषित करने की अनुमति देता है ताकि बाद में प्रोग्राम में एरे को गतिशील रूप से आकार दिया जा सके। इस तकनीक के साथ, आप मूल रूप से एक शून्य संदर्भ बना रहे हैं और बाद में एक newकीवर्ड के साथ अनुरोधित स्मृति स्थानों के गतिशील रूप से आवंटित खिंचाव पर उस संदर्भ को इंगित करते हैं :

int[] integers;
integers = new int[32];

धन्यवाद।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.