[c#] الفرق بين المعلمات ref و out في .NET



8 Answers

لماذا يحتوي C # على "ref" و "out"؟

لا يُطلب من المتصل لطريقة تأخذ معلماً خارجياً أن يعين للمتغير الذي تم تمريره كمعلمة خارج قبل النداء ؛ ومع ذلك ، مطلوب من المستدعي تعيين إلى المعلمة الخروج قبل العودة.

على النقيض من المعلمات ref تعتبر المعينة في البداية من قبل المتصل. على هذا النحو ، لا يطلب من المستدعي تخصيصه لمعلمة المرجع قبل الاستخدام. يتم تمرير معلمات Ref داخل وخروج من أسلوب.

لذلك ، out يعني ، في حين أن ref هو ref والخارج.

هذه تتوافق بشكل وثيق مع المعلمات [out] و [in,out] لواجهات COM ، وميزات المعلمات الخارجية هي أن المتصلين لا يحتاجون إلى تمرير كائن تم تخصيصه مسبقًا في الحالات التي لا تكون مطلوبة فيها بالطريقة التي يتم استدعاؤها - وهذا يتجنب كل من تكلفة التخصيص وأي تكلفة قد تكون مقترنة مع التعبئة (على الأرجح مع COM ولكن ليس غير شائعة في .NET).

Question

ما هو الفرق بين المعلمات ref و out في .NET؟ ما هي الحالات التي يمكن للمرء فيها أن يكون أكثر فائدة من الآخر؟ ماذا يمكن أن يكون مقتطف شفرة حيث يمكن استخدام أحدهما والآخر لا يمكن؟




المعلمة out هي معلمة ref مع سمة Out() خاصة مضافة. إذا تم الإعلان عن معلمة إلى طريقة C # ، فسيطلب المحول البرمجي كتابة المعلمة قبل قراءتها وقبل أن تعود الطريقة. إذا كان C # يستدعي أسلوباً تتضمن Out() سمة Out() ، سيقوم المترجم ، لأغراض تحديد ما إذا كان سيتم الإبلاغ عن أخطاء "متغير غير معرف" ، بالتظاهر بأن المتغير قد تمت كتابته مباشرة قبل استدعاء الطريقة. لاحظ أنه نظرًا لأن لغات .net الأخرى لا تقوم بإرفاق نفس المعنى للسمة Out() ، فمن الممكن أن يؤدي استدعاء إجراء مع معلمة out إلى ترك المتغير المعني غير متأثر. إذا تم استخدام متغير كمعامل خارجي قبل تعيينه بالتأكيد ، سيعمل مترجم C # على إنشاء تعليمات برمجية للتأكد من أنه يتم مسحها في مرحلة ما قبل استخدامها ، ولكن إذا ترك هذا المتغير النطاق أو أعاد إدخاله ، فليس هناك ضمان أنه سيتم مسحها مرة أخرى.




مرجع و خارج المعلمات:

يتم استخدام المعلمات out و ref لإرجاع القيم في المتغير نفسه ، التي تقوم بتمريرها كوسيطة أسلوب. هذه المعلمات مفيدة للغاية عندما تحتاج الطريقة الخاصة بك إلى إرجاع أكثر من قيمة واحدة.

يجب تعيين قيمة لمعلمة خارج في جسم طريقة الكالي ، وإلا لن يتم تجميع هذه الطريقة.

مرجع المرجع: يجب أن يتم التهيئة قبل المرور إلى الأسلوب. الكلمة الأساسية ref على معلمة أسلوب يؤدي أسلوب للإشارة إلى نفس المتغير الذي تم تمريره كمعلمة إدخال للأسلوب نفسه. إذا قمت بإجراء أي تغييرات على المتغير ، فسوف تنعكس في المتغير.

int sampleData = 0; 
sampleMethod(ref sampleData);

مثال على مرجع Ref

public static void Main() 
{ 
 int i = 3; // Variable need to be initialized 
 sampleMethod(ref i );  
}

public static void sampleMethod(ref int sampleData) 
{ 
 sampleData++; 
} 

Out Out Parameter: ليس من الضروري أن يتم التهيئة قبل المرور إلى Method. يمكن استخدام المعلمة الخارجية لإرجاع القيم في نفس متغير تمرير كمعلمة من الأسلوب. ستنعكس أي تغييرات يتم إجراؤها على المعلمة في المتغير.

 int sampleData; 
 sampleMethod(out sampleData);

خروج خارج المعلمة

public static void Main() 
{ 
 int i, j; // Variable need not be initialized 
 sampleMethod(out i, out j); 
} 
public static int sampleMethod(out int sampleData1, out int sampleData2) 
{ 
 sampleData1 = 10; 
 sampleData2 = 20; 
 return 0; 
} 



لا يلزم تعيين معلمات ref في الدالة ، بينما يجب أن تكون المعلمات الخارجية مرتبطة بقيمة قبل إنهاء الوظيفة. قد يتم تمرير المتغيرات التي تم تمريرها أيضًا إلى دالة دون أن يتم تهيئتها.







خارج و ref هي نفسها تماما مع الاستثناء الذي لا يلزم تهيئة المتغيرات خارج قبل إرسالها إلى الهاوية. أنا لست ذكية ، أنا cribbed ذلك من مكتبة MSDN :).

ولكن لكي تكون أكثر وضوحًا بشأن استخدامها ، فإن معنى المعدل هو أنه في حالة تغيير مرجع هذا المتغير في شفرتك ، فإن الخروج والرجوع سيؤدي إلى تغيير متغير الاتصال الخاص بك أيضًا. في الكود أدناه ، سيكون المتغير الرئيسي مرجعًا لـ newGuy بمجرد عودته من المكالمة إلى doStuff. إذا لم يكن المرجع (أو الخروج) لن يتم تغيير المرجع.

private void newEmployee()
{
    Person ceo = Person.FindCEO();
    doStuff(ref ceo);
}

private void doStuff(ref Person employee)
{
    Person newGuy = new Person();
    employee = newGuy;
}



عند إعلان معلمة خارج في تعريف الطريقة ، يجب أن يقوم جسم الطريقة بتعيين قيمة للمتغير الخارجي قبل العودة. وبالتالي ، تقع على عاتق الطريقة المسماة لتعيين القيمة للمعلمة المهلة قبل إرجاعها.

عندما يتم تحديد معلمة ref في الطريقة ، يجب أن تكون الوسيطة التي يتم تمريرها أثناء استدعاء الطريقة قد عينت القيمة. وبالتالي ، تقع على عاتق المتصل تعيين القيمة لوسيطة المرجع قبل استدعاء الطريقة.




يتم تهيئة المعلمات out من قبل طريقة تسمى ، يتم تهيئة المعلمات ref قبل استدعاء الأسلوب. لذلك ، يتم استخدام المعلمات out عندما تحتاج فقط إلى الحصول على قيمة إرجاع ثانوي ، يتم استخدام معلمات ref للحصول على قيمة وإمكانية إرجاع تغيير إلى تلك القيمة (بشكل ثانوي إلى قيمة الإرجاع الرئيسية).




مثال لـ OUT: يتم تهيئة القيمة المتغيرة بعد الانتقال إلى الطريقة. في وقت لاحق يتم إرجاع نفس القيمة إلى الطريقة الرئيسية.

namespace outreftry
{
    class outref
    {
        static void Main(string[] args)
        {
            yyy a = new yyy(); ;

            // u can try giving int i=100 but is useless as that value is not passed into
            // the method. Only variable goes into the method and gets changed its
            // value and comes out. 
            int i; 

            a.abc(out i);

            System.Console.WriteLine(i);
        }
    }
    class yyy
    {

        public void abc(out int i)
        {

            i = 10;

        }

    }
}

انتاج:

10

===============================================

مثال المرجع: يجب تهيئة المتغير قبل الانتقال إلى الطريقة. سيتم إرجاع نفس القيمة أو القيمة المعدلة في وقت لاحق إلى الطريقة الرئيسية.

namespace outreftry
{
    class outref
    {
        static void Main(string[] args)
        {
            yyy a = new yyy(); ;

            int i = 0;

            a.abc(ref i);

            System.Console.WriteLine(i);
        }
    }
    class yyy
    {

        public void abc(ref int i)
        {
            System.Console.WriteLine(i);
            i = 10;

        }

    }
}

انتاج:

    0
    10

=================================

نأمل في واضحة الآن.




Related



Tags

c# c#   .net .net