खोज…


वाक्य - विन्यास

  • संदर्भ से गुज़रना: सार्वजनिक शून्य डबल (रेफरी int नंबरट्यूड डबल) {}

टिप्पणियों

परिचय

मान प्रकार

मान प्रकार दो के सरल होते हैं। मान प्रकार का उपयोग अक्सर डेटा का प्रतिनिधित्व करने के लिए किया जाता है। एक पूर्णांक, एक बूलियन या 3 डी अंतरिक्ष में एक बिंदु सभी अच्छे मूल्य प्रकार के उदाहरण हैं।

मूल्य प्रकार (संरचनाएं) संरचना कीवर्ड का उपयोग करके घोषित किए जाते हैं। नई संरचना कैसे घोषित करें, इसके उदाहरण के लिए सिंटैक्स अनुभाग देखें।

सामान्यतया, हमारे पास 2 कीवर्ड होते हैं जिनका उपयोग मूल्य प्रकार घोषित करने के लिए किया जाता है:

  • structs
  • enumerations

संदर्भ प्रकार

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

C # में आमतौर पर हमारे पास यह संदर्भ प्रकार होते हैं:

  • कक्षाएं
  • प्रतिनिधियों
  • इंटरफेस

नए संदर्भ प्रकार (कक्षाएं) वर्ग कीवर्ड का उपयोग करके घोषित किए जाते हैं। एक उदाहरण के लिए, एक नया संदर्भ प्रकार घोषित करने के लिए सिंटैक्स अनुभाग देखें।

प्रमुख अंतर

संदर्भ प्रकार और मूल्य प्रकार के बीच प्रमुख अंतर नीचे देखा जा सकता है।

स्टैक पर मान प्रकार मौजूद हैं, संदर्भ प्रकार ढेर पर मौजूद हैं

यह दोनों के बीच अक्सर उल्लिखित अंतर है, लेकिन वास्तव में, यह क्या उबलता है कि जब आप सी # में एक मूल्य प्रकार का उपयोग करते हैं, जैसे कि एक इंट, प्रोग्राम उस चर का उपयोग उस मूल्य को सीधे संदर्भित करने के लिए करेगा। यदि आप इंट माइन = 0 कहते हैं, तो वेरिएबल माइन सीधे 0 को संदर्भित करता है, जो कुशल है। हालाँकि, संदर्भ प्रकार वास्तव में अंतर्निहित वस्तु के संदर्भ के अनुसार (जैसा कि नाम से पता चलता है) एक पकड़ है, यह C ++ जैसी अन्य भाषाओं में संकेत करने वाला है।

आप इस के प्रभावों को तुरंत नहीं देख सकते हैं, लेकिन प्रभाव वहाँ हैं, शक्तिशाली हैं और सूक्ष्म हैं। उदाहरण के लिए कहीं और संदर्भ प्रकार बदलने पर उदाहरण देखें।

यह अंतर निम्नलिखित अन्य मतभेदों का प्राथमिक कारण है, और जानने लायक है।

जब आप उन्हें किसी विधि में बदलते हैं तो मूल्य प्रकार नहीं बदलते हैं, संदर्भ प्रकार करते हैं

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

अधिक जानकारी के लिए तरीकों में मूल्य प्रकार बनाम संदर्भ प्रकार का उदाहरण देखें।

अगर मैं उन्हें बदलना चाहता हूँ तो क्या होगा?

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

मान प्रकार शून्य नहीं हो सकते, संदर्भ प्रकार हो सकते हैं

बहुत अधिक के रूप में यह कहता है, आप एक संदर्भ प्रकार के लिए अशक्त असाइन कर सकते हैं, जिसका अर्थ है कि आपके द्वारा असाइन किए गए चर का कोई वास्तविक ऑब्जेक्ट नहीं हो सकता है। हालांकि, मूल्य प्रकारों के मामले में, यह संभव नहीं है। हालाँकि, आप अशक्त का उपयोग कर सकते हैं, यदि आपके मूल्य प्रकार को अशक्त बनाने की अनुमति है, अगर यह एक आवश्यकता है, हालांकि यदि यह ऐसी चीज है जिस पर आप विचार कर रहे हैं, तो दृढ़ता से सोचें कि क्या कोई वर्ग यहां सबसे अच्छा दृष्टिकोण नहीं हो सकता है, अगर यह आपका अपना है प्रकार।

मूल्यों को अन्यत्र बदलना

public static void Main(string[] args)
{
    var studentList = new List<Student>();
    studentList.Add(new Student("Scott", "Nuke"));
    studentList.Add(new Student("Vincent", "King"));
    studentList.Add(new Student("Craig", "Bertt"));

    // make a separate list to print out later
    var printingList = studentList; // this is a new list object, but holding the same student objects inside it

    // oops, we've noticed typos in the names, so we fix those
    studentList[0].LastName = "Duke";
    studentList[1].LastName = "Kong";
    studentList[2].LastName = "Brett";

    // okay, we now print the list
    PrintPrintingList(printingList);
}

private static void PrintPrintingList(List<Student> students)
{
    foreach (Student student in students)
    {
        Console.WriteLine(string.Format("{0} {1}", student.FirstName, student.LastName));
    }
}

आप देखेंगे कि भले ही टाइपिंग के बाद छात्र के नाम में सुधार से पहले मुद्रण सूची सूची बनाई गई थी, प्रिंटप्रिंटिंग पद्धति अभी भी सही नामों को छापती है:

Scott Duke
Vincent Kong
Craig Brett

ऐसा इसलिए है क्योंकि दोनों सूची एक ही छात्रों के संदर्भों की एक सूची रखती हैं। SO अंतर्निहित छात्र वस्तु को बदलकर या तो सूची द्वारा उपयोग के लिए प्रचारित करता है।

यहाँ छात्र वर्ग कैसा दिखेगा।

public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Student(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
}

संदर्भ से गुजर रहा है

यदि आप चाहते हैं कि मान प्रकार बनाम संदर्भ प्रकार विधियाँ उदाहरण में ठीक से काम करें, तो अपने विधि हस्ताक्षर में रेफरी कीवर्ड का उपयोग उस पैरामीटर के लिए करें, जिसे आप संदर्भ द्वारा पास करना चाहते हैं, साथ ही जब आप विधि को कॉल करें।

public static void Main(string[] args)
{
    ...
    DoubleNumber(ref number); // calling code
    Console.WriteLine(number); // outputs 8
    ...
}
public void DoubleNumber(ref int number)
{
    number += number;
}

इन परिवर्तनों को करने से उम्मीद के मुताबिक नंबर अपडेट हो जाएगा, मतलब नंबर के लिए कंसोल आउटपुट 8 होगा।

संदर्भ कीवर्ड का उपयोग करके संदर्भ से गुजरना।

प्रलेखन से :

C # में, तर्कों को मान द्वारा या संदर्भ द्वारा पैरामीटर में पारित किया जा सकता है। संदर्भ द्वारा पास होने से फ़ंक्शन सदस्यों, विधियों, गुणों, अनुक्रमणिका, ऑपरेटर और निर्माणकर्ताओं को मापदंडों के मूल्य को बदलने में सक्षम बनाता है और यह परिवर्तन कॉलिंग वातावरण में बनी रहती है। संदर्भ द्वारा एक पैरामीटर पास करने के लिए, ref या out कीवर्ड का उपयोग करें।

के बीच अंतर ref और out वह यह है कि out का मतलब है पारित कर दिया पैरामीटर समारोह ends.in विपरीत के साथ पारित कर दिया मानकों से पहले असाइन करना होता है कि ref बदला जा सकता है या अपरिवर्तित छोड़ दिया है।

using System;

class Program
{
    static void Main(string[] args)
    {
        int a = 20;
        Console.WriteLine("Inside Main - Before Callee: a = {0}", a);
        Callee(a);
        Console.WriteLine("Inside Main - After Callee: a = {0}", a);
        
        Console.WriteLine("Inside Main - Before CalleeRef: a = {0}", a);
        CalleeRef(ref a);
        Console.WriteLine("Inside Main - After CalleeRef: a = {0}", a);
     
        Console.WriteLine("Inside Main - Before CalleeOut: a = {0}", a);
        CalleeOut(out a);
        Console.WriteLine("Inside Main - After CalleeOut: a = {0}", a);
        
        Console.ReadLine();
    }

    static void Callee(int a)
    {
        a = 5;
        Console.WriteLine("Inside Callee a : {0}", a);
    }

    static void CalleeRef(ref int a)
    {
        a = 6;
        Console.WriteLine("Inside CalleeRef a : {0}", a);
    }
    
    static void CalleeOut(out int a)
    {
        a = 7;
        Console.WriteLine("Inside CalleeOut a : {0}", a);
    }
}

आउटपुट :

Inside Main - Before Callee: a = 20
Inside Callee a : 5
Inside Main - After Callee: a = 20
Inside Main - Before CalleeRef: a = 20
Inside CalleeRef a : 6
Inside Main - After CalleeRef: a = 6
Inside Main - Before CalleeOut: a = 6
Inside CalleeOut a : 7
Inside Main - After CalleeOut: a = 7

असाइनमेंट

var a = new List<int>();
var b = a;
a.Add(5);
Console.WriteLine(a.Count); // prints 1 
Console.WriteLine(b.Count); // prints 1 as well

एक के एक चर करने के लिए नियत List<int> की एक प्रति का निर्माण नहीं करता List<int> । इसके बजाय, यह List<int> के संदर्भ को कॉपी करता है। हम ऐसे प्रकार कहते हैं जो इस प्रकार के संदर्भ प्रकारों का व्यवहार करते हैं

विधि मापदंडों के साथ अंतर रेफरी और बाहर

संदर्भ द्वारा मान प्रकार पास करने के दो संभावित तरीके हैं: ref और out । अंतर यह है कि इसे ref के साथ मान को आरंभीकृत किया जाना चाहिए, लेकिन जब इसे out पास नहीं किया out । का उपयोग करते हुए out सुनिश्चित चर विधि कॉल के बाद एक मूल्य है कि:

public void ByRef(ref int value)
{
    Console.WriteLine(nameof(ByRef) + value);
    value += 4;
    Console.WriteLine(nameof(ByRef) + value);
}

public void ByOut(out int value)
{
    value += 4 // CS0269: Use of unassigned out parameter `value'  
    Console.WriteLine(nameof(ByOut) + value); // CS0269: Use of unassigned out parameter `value'  

    value = 4;
    Console.WriteLine(nameof(ByOut) + value);
}

public void TestOut()
{
    int outValue1;
    ByOut(out outValue1); // prints 4

    int outValue2 = 10;   // does not make any sense for out
    ByOut(out outValue2); // prints 4
}

public void TestRef()
{
    int refValue1;
    ByRef(ref refValue1); // S0165  Use of unassigned local variable 'refValue'

    int refValue2 = 0;
    ByRef(ref refValue2); // prints 0 and 4

    int refValue3 = 10;
    ByRef(ref refValue3); // prints 10 and 14
}

पकड़ है कि का उपयोग करना है out पैरामीटर must विधि रवाना होने से पहले प्रारंभ, इसलिए निम्न विधि के साथ संभव है ref नहीं बल्कि साथ out :

public void EmtyRef(bool condition, ref int value)
{
    if (condition)
    {
        value += 10;
    }
}

public void EmtyOut(bool condition, out int value)
{
    if (condition)
    {
        value = 10;
    }
} //CS0177: The out parameter 'value' must be assigned before control leaves the current method

ऐसा इसलिए है क्योंकि यदि condition नहीं है, तो value बताए चला जाता है।

रेफरी बनाम पैरामीटर

कोड

class Program
{
    static void Main(string[] args)
    {
        int a = 20;
        Console.WriteLine("Inside Main - Before Callee: a = {0}", a);
        Callee(a);
        Console.WriteLine("Inside Main - After Callee: a = {0}", a);
        Console.WriteLine();

        Console.WriteLine("Inside Main - Before CalleeRef: a = {0}", a);
        CalleeRef(ref a);
        Console.WriteLine("Inside Main - After CalleeRef: a = {0}", a);
        Console.WriteLine();

        Console.WriteLine("Inside Main - Before CalleeOut: a = {0}", a);
        CalleeOut(out a);
        Console.WriteLine("Inside Main - After CalleeOut: a = {0}", a);
        Console.ReadLine();
    }

    static void Callee(int a)
    {
        a += 5;
        Console.WriteLine("Inside Callee a : {0}", a);
    }

    static void CalleeRef(ref int a)
    {
        a += 10;
        Console.WriteLine("Inside CalleeRef a : {0}", a);
    }

    static void CalleeOut(out int a)
    {
        // can't use a+=15 since for this method 'a' is not intialized only declared in the method declaration
        a = 25; //has to be initialized
        Console.WriteLine("Inside CalleeOut a : {0}", a);
    }
}

उत्पादन

Inside Main - Before Callee: a = 20
Inside Callee a : 25
Inside Main - After Callee: a = 20

Inside Main - Before CalleeRef: a = 20
Inside CalleeRef a : 30
Inside Main - After CalleeRef: a = 30

Inside Main - Before CalleeOut: a = 30
Inside CalleeOut a : 25
Inside Main - After CalleeOut: a = 25


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow