تفاوت بین پارامتر Out و Ref در #C

سه شنبه 14 مهر 1394

چگونه از يك تابع بيش از يك خروجي دريافت كنيم؟ظاهرا به نظر مي رسد كه توابع فقط مي توانند يك خروجی داشته باشند و بلافاصله پس از فراخواني return كار تابع پايان يافته است. اما در سي شارپ دو كلمه ي كليدي به نام هاي ref و out اضافه شده اند كه اين امر را ممکن مي سازند.

تفاوت بین پارامتر Out و Ref در #C

 پارامترهای Out و Ref یکی از موضوعات#C هستند که  بیشترین اشتباه در آنها رخ می دهد. در حالت پیش فرض پارامترها به صورت Value ارسال می شوند و Out و Ref کمک می کنند پارامتر از طریق منبع(Reference) به تابع ارسال شوند. در ادامه شیوه های مختلف ارسال پارامتر را به تفصیل توضیح می دهیم.

به طور کلی سه روش برای ارسال پارامتر وجود دارد:

 ارسال به صورت Value(مقدار)، ارسال به صورت Ref و  ارسال به صورت Out

ارسال پارمتر به صورت value:

ارسال به روش value parameter به صورت پیش فرض می باشد . هنگامی که ما متغیری (variable)  به  ورودی یک متد ارسال می کنیم ، در صورتی که نوع آن پارامتر را ذکر نکنیم به صورت مقداری ارسال می شود. به عبارت دیگر مقدار آن متغیر به تابع فرستاده می شود .  در صورت تغییر مقدار متغیر در بدنه تابع ، تغییری در پارامتر ارسال شده ، ایجاد نمی شود. هر گاه در اعلان پارامترها از کلمات کلیدی ref  و out استفاده نشود، به صورت value فرستاده می شود.

کد زیر مثالی در این مورد است.

تابع زیر را در پنجره کنسول بنویسید:

    public void plus(int t)
        {
            Console.WriteLine("the plus function run : "+ ++t);
        }

فراخوانی تابع در بدنه:

int t = 10;
            plus(t);
            Console.WriteLine("the t variable value :  " + t);
            Console.ReadLine();

خروجی برنامه:

the plus function run : 11
the t variable value :  10

دیدید که هر تغییری در بدنه تابع تاثیری در پارمتر ندارد.

شکل زیر به طور خلاصه ارسال پارامتر با مقدار(Value) رانشان می دهد:

ارسال پارمتر به صورت ref :

وقتی متغیری را به صورت ref به یک تابع ارسال می کنیم ، مقدار متغیر ارسال نمی شود بلکه آدرس متغییر به بدنه متد فرستاده می شود و هر تغییری درمتغیر محلی  روی متغیر اصلی نیز اعمال می شود. به این نوع پارمترها ارجاعی می گویند.

برای مثال کد تابع زیر را در کنسول وارد کنید:

public void plus(ref int t)
        {
            Console.WriteLine("the plus function run : "+ ++t);
        }

فراخوانی تابع:

int t = 10;
            plus(ref t);
            Console.WriteLine("the t variable value :  " + t);
            Console.ReadLine();

خروجی:

the plus function run : 11
the t variable value :  11

می بینید که تغییر در متغیر محلی روی پارمتر اصلی اعمال شد.

نکته: نوشتن کلمه کلیدی ref هم در ارسال به تابع وهم در دریافت پارمتر الزامی می باشد.

نکته:قبل از ارسال پارمتر به صورت ref حتما باید متغییر مقدار داشته باشد.

شکل زیر ارسال پارامتر به صورت منبع (Reference) را نشان می دهد:

ارسال پارمتر به صورت out :

این شیوه ارسال هم  به صورت ارجاعی می باشد. این پارامترها زمانی استفاده می شود که قصد ارسال اطلاعاتی به  متد را  نداشته باشیم، بلکه می خواهیم اطلاعات از  متد برگردد.

نیازی به مقدار دهی قبل از ارسال به متد نیست ولی حتما باید درون تابع (قبل از بازگشت به متدی فراخوانی شده) مقدار بگیرد.


تابع را زیر را مجدد در کنسول وارد کنید:

 public void plus(out int t)
        {
            //مقدار دهی درون تابع
            t = 10;
            Console.WriteLine("the plus function run : "+ ++t);
        }

فراخوانی تابع:

//نیازی به گرفتن مقدار نیست
            int t;
            Program.plus(out t);
            Console.WriteLine("the t variable value :  " + t);
            Console.ReadLine();

خروجی:

the plus function run : 11
the t variable value :  11

نکته:

آرگومان های out نیازی به مقداردهی اولیه ندارند و برای خروجی از آن استفاده می کنیم.

آرگومان های ref  حتما باید مقدار دهی شوند و هنگامی که بخواهیم اطلاعاتی را به متد ارسال کنیم، پس از دستکاری شدن، اطلاعات برگشت داده شود.

شکل زیر ارسال پارامتر به صورت Out را به طور خلاصه نشان می دهد:

مطالب گفته شده را به صورت زیر می توان جمع بندی کرد:

Out(1 و Ref به ارسال پارامترها توسط منبع(Reference) کمک می کنند.

2)در REF با داده های منبع نیز از فراخواننده  به پذیرنده و بالعکس منتقل می شوند. این برای مثال از فراخواننده به پذیرنده و بالعکس انجام می گیرد. و به صورت روش دو طرفه است.

3)در OUT فقط منبع ارسال می شود و داده تغییر یافته از فراخواننده به پذیرنده ارسال می شود. این یک روش یک طرفه است.

4)در OUT اگر داده از تابع فراخواننده ارسال شود دور انداخته خواهد شد و متغیر داخل تابع مقدار دهی خواهد شد. تصویر زیر خلاصه ای از موارد گفته شده را نشان می دهد.

آموزش سی شارپ

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 12k بازدید
  • 7 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید