کلمه کلیدی ref باعث می شود که آرگومان ها بصورت ارجاعی پاس داده شوند. اثر آن به این شکل است که وقتی روند اجرایی برنامه به جایی که متد فراخوانی شده بر می گردد، هر تغییری که متد روی پارامتر ref انجام داده بر روی آن متغیر منعکس می شود.
نکته
مفهوم پاس دادن با مرجع را با مفهوم نوع های مرجع اشتباه نگیرید. این دو مفهوم با هم ارتباطی ندارند؛ یک پارامتر متد فارغ از اینکه نوع مقداری باشد یا نوع مرجع می تواند با ref اصلاح شود. بنابراین وقتی یک نوع مقداری بصورت ارجاعی به متد پاس داده می شود هیچ عمل boxing انجام نمی گیرد.
برای استفاده از یک پارامتر ref ، هم در اعلان متد و هم در فراخوانی متد باید از کلیدواژه ref استفاده کرد. برای مثال:
class RefExample { static void Method(ref int i) { i = 44; } static void Main() { int val = 0; Method(ref val); // val is now 44 } }
آرگومانی که به یک پارامتر ref پاس داده می شود باید اول مقداردهی اولیه شود. از این لحاظ ref با out که آرگومان هایش مجبور نیستند قبل از پاس داده شدن صریحا" مقداردهی اولیه شوند، متفاوت است.
هرچند ref و out باعث رفتارهای متفاوتی در زمان اجرا می شوند، در زمان کامپایل به عنوان امضای متد در نظر گرفته نمی شوند. بنابراین متدهایی که تنها تفاوت آنها در این است که یکی آرگومان ref گرفته و دیگری آرگومان out ، نمی توانند overload شوند. برای مثال کد زیر کامپایل نخواهد شد.
class CS0663_Example { // Compiler error CS0663: "Cannot define overloaded // methods that differ only on ref and out". public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } }
اگر یک متد ، آرگومان ref یا out بگیرد و متد دیگر هیچکدام از این آرگومان ها را نگیرد، عمل overload کردن انجام می گیرد.
class RefOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(ref int i) { } }
پراپرتی ها با متغیرها تفاوت دارند. آنها در واقع متد هستند و بنابراین نمی توان آنها بصورت پارامتر ref پاس داد.
مثال
پاس دادن نوع های مقداری بصورت مرجع که پیش از این در همین تاپیک توضیح داده شد مفید است، اما کلمه کلیدی ref برای پاس دادن نوع های مرجع نیز کاربرد دارد. پاس دادن نوع های مرجع به متدهای فراخوانی شده امکان دستکاری شیئی که مرجع به آن اشاره دارد را می دهد، زیرا خود مرجع نیز بصورت ارجاعی به متد پاس داده شده. مثال زیر نشان می دهد که وقتی یک نوع مرجع با پارامتر ref پاس داده می شود، خود شیئی نیز می تواند تغییر کند.
class RefExample2 { static void Method(ref string s) { s = "changed"; } static void Main() { string str = "original"; Method(ref str); Console.WriteLine(str); } } // Output: changed