"> استفاده از ref در سی شارپ | آموزش سی شارپ | ام اس پی سافت

استفاده از ref در سی شارپ

ref

کلمات کلیدی  Ref و  out در پارامترهای متد استفاده می شوند. این مقاله به شما کمک می کند تصمیم بگیرید که آیا از کلمه کلیدی Ref یا Out استفاده می کنید؟ ، به خصوص وقتی که انواع پارامتر از نوع مقدار هستند.

دو کلیدواژه به نام های ref و out در سی شارپ داریم.

این کلیدواژه ها در شرایطی که نیاز به بازگردانی بیش از یک مقدار از یک متد داریم، کمک کننده هستند.

اما نکته ی مهم تری در کاربرد کلیدواژه ی ref وجود دارد.

بر اساس MSDN، ref بدین معناست:

“کلیدواژه ی ref موجب می شود که یک آرگومان از طریق ارجاع ارسال شود، و نه از طریق مقدار.

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

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

استفاده از ref در سی شارپ

بیایید سعی کنیم این مسئله را با مثالی درک کنیم:

متدی به نام GetData داریم که یک پارامتر عددی صحیح (integer) می گیرد.

درون این متد، این مقدار را بروز خواهیم کرد.

سپس، این متد را فراخوانی کرده و مقدار پارامتر را  پیش از فراخوانی متد، درون متد، و پس از اجرای متد چاپ می کنیم.

بنابراین، کد آن به شکل زیر خواهد بود:

static void Main(string[] args)  
{  
     int a = 4;  
     Console.WriteLine("Value before method call is: " + a);  
     GetData(a);  
     Console.WriteLine("Value after method call is: " + a);  
     Console.ReadKey();  
}  
  
public static void GetData(int a)  
{  
   a = a + 999;  
   Console.WriteLine("Value inside method is: " + a);  
}  

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

خروجی به این صورت خواهد بود:

Value before method call is: 4  
Value inside method is: 1003  
Value after method call is: 4  

حال، پارامتر را تغییر داده و کلیدواژه ی ref را به آن پیوند می دهیم. مجدد این متد را فراخوانی کرده و مقادیر آن را چاپ می کنیم.

بنابراین، کد آن بصورت زیر خواهد بود.

public static void GetData(ref int a)  
{  
      a = a + 999;  
      Console.WriteLine("Value inside method is: " + a);  
} 

برنامه را اجرا کرده و تفاوت بین این نتیجه و نتیجه ی اجرای نخست را مشاهده کنید.

Value before method call is: 4  
Value inside method is: 1003  
Value after method call is: 1003  

این بار، مقدار پارامتر پس از اجرای متد مشابه با آنچه که درون متد تنظیم شده بود می باشد.

علت آن این است که بکارگیری کلیدواژه ی ref موجب می شود که پارامتر به وسیله مرجع منتقل شود و نه با مقدار واقعی.

به بیان دیگر، به دلیل استفاده از کلیدواژه ی ref، مقدار حقیقی پارامتر با متد به اشتراک گذاشته شده بود.

لذا هر تغییر در مقدار پارامتر درون متد، مقدار اصلی را نیز بروز کرده است.

اکنون، بیایید سعی کنیم مورد مشابهی را با یک نوع مرجع بررسی کنیم.

کلاسی جدید به نام TestClass اضافه کرده و دو ویژگی به نام های Id و Name می افزاییم.

signature متد را تغییر می دهیم تا پارامتری از نوع TestClass را، بدون کلیدواژه ی ref، ارسال کند.

درون متد، نوع کلاس TestClass را مجددا مقداردهی اولیه کرده و مقادیر ویژگی ها را بروز می کنیم.

مجددا مقادیر را پیش از فراخوانی متد، درون متد و پس از فراخوانی متد چاپ می کنیم.

بنابراین کد آن به شکل زیر خواهد بود،

static void Main(string[] args)  
{  
            TestClass testClass = new TestClass()  
            {  
                Id = 1,  
                Name = "Test User"  
  
            };  
            Console.WriteLine("Before method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
            GetData(testClass);  
            Console.WriteLine("After method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
  
            Console.ReadKey();  
}  
  
public static void GetData(TestClass testClass)  
{  
            testClass = new ConsoleApplication1.Program.TestClass();  
            testClass.Id += 999;  
            testClass.Name += "_Updated";  
            Console.WriteLine("Inside method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
 }  
  
 public class TestClass  
 {  
            public int Id  
            {  
                get;  
                set;  
            }  
  
            public String Name  
            {  
                get;  
                set;  
            }  
  }  

کد را اجرا کرده و نتایج را مشاهده کنید.

Before method call Name is: Test User and ID is:1  
Inside method call Name is: _Updated and ID is:999  
After method call Name is: Test User and ID is:1   

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

هنگامی که پارامتر درون متد مجددا مقداردهی اولیه می شود، اشاره گر جدیدی ایجاد می کنیم که جایگزین کپی اشاره گر (دریافت شده در فراخوانی متد) می شود.

لذا داده ها درون متد تغییر کرده اند اما پس از اجرای متد به همان صورت باقی مانده اند.

حال بیایید متد را جهت ارسال اشاره گر داده ها با استفاده از کلیدواژه ی ref تغییر دهیم.

static void Main(string[] args)  
{  
            TestClass testClass = new TestClass()  
            {  
                Id = 1,  
                Name = "Test User"  
  
            };  
            Console.WriteLine("Before method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
            GetData(ref testClass);  
            Console.WriteLine("After method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
  
            Console.ReadKey();  
}
    
public static void GetData(ref TestClass testClass)  
{  
            testClass = new ConsoleApplication1.Program.TestClass();  
            testClass.Id += 999;  
            testClass.Name += "_Updated";  
            Console.WriteLine("Inside method call Name is: " + testClass.Name + " and ID is:" + testClass.Id);  
}  

کد را اجرا کرده و تفاوت نتایج را مشاهده کنید.

Before method call Name is: Test User and ID is:1  
Inside method call Name is: _Updated and ID is:999  
After method call Name is: _Updated and ID is:999  

این بار، مقادیر پس از اجرای متد نیز تغییر کرده اند.

دلیل آن این است که این بار اشاره گر حقیقی را با متد به اشتراک گذاشتیم و نه کپی آن را.

لذا تغییرات در اشاره گر (از طریق مقداردهی اولیه ی مجدد TestClass درون متد)، اشاره گر اصلی (نمونه ی TestClass در متد Main) را بروز کرده است.

بنابراین، مقادیر جدیدی پس از اجرای متد چاپ شده اند.

این چیزی است که MSDN می گوید، یعنی کلیدواژه ی ref موجب می شود که یک آرگومان از طریق مرجع ارسال شود، و نه از طریق مقدار.

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

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

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

  • پسورد: www.mspsoft.com
زهره سلطانیان

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

کدیشن ! مارکت پروژه های برنامه نویسی راه اندازی شدیه توکه پا بریم ببینم