آموزش: آموزش برنامه نویسی شئ گرا در زبان سی شارپ -قسمت بیست و چهارم - آشنایی با مفهوم Type Casting و انواع Cast ها
علاقه مندان به مبحث شیرین برنامه نویسی ،
بعد از یک وقفه طولانی در خدمت شما هستم با قسمت بیست و چهارم از سری
آموزشی برنامه نویسی به زبان سی شارپ. در این قسمت با مبحث Type Casting و
انواع Cast ها در زبان سی شارپ آشنا بشیم. ابتدا یک توضیح اولیه راجع موضوع
Type Casting بدم و بعد بریم سراغ مثال ها و کدها. همانطور که در قسمت های
قبلی گفته شد، در زبان سی شارپ انواع نوع داده برای ذخیره مقادیر وجود
دارد. برای مثال، نوع داده int برای ذخیره مقادیر عددی صحیح و نوع داده
string برای نوع داده رشته استفاده می شود. اما بعضی اوقات هست که تصمیم
داریم یک نوع داده را به یک نوع داده دیگر تبدیل کنیم. به تبدیل انواع داده
به یکدیگر در زبان سی شارپ Type Casting می گویند. در قسمت های قبلی با
یکی از این تبدیل ها آشنا شدیم: استفاده از متد Parse در نوع های داده
اولیه. برای مثال زمانی که می خواستیم نوع داده رشته را به عددی تبدیل کنیم
به صورت زیر عمل می کردیم:
int number = int.Parse("12");
کد بالا، رشته 12 را به نوع عددی int تبدیل کرده و داخل متغیر number ذخیره می کند. در این قسمت از آموزش، به تفصیل راجع به مبحث Type Casting صحبت کرده و انواع و اقسام آن را توضیح می دهیم.
انواع Type Casting در زبان سی شارپ
در زبان سی شارپ، دو نوع تبدیل نوع به یکدیگر با روش های مختلف وجود دارد:
- تبدیل نوع Implicit: در این نوع تبدیل بدون نیاز به نوشتن کد خاصی، می توان مقدار یک متغیر را داخل یک متغیر دیگر ریخت. برای مثال می توان نوع عددی int را بدون هیچ مشکلی به نوع داده long تبدیل کرد
- تبدیل نوع Explicit: در این نوع تبدیل، ما می بایست حتماً با نوشتن یکسری دستورات خاص، نوع ها را به یکدیگر تبدیل کنیم، برای مثال نمی توان نوع عددی long را به صورت مستقیم به نوع عددی int تبدیل کرد، زیرا نوع عددی long ظرفیت بیشتری از int دارد و ریختن مقدار long داخل int به صورت مستقیم یا implicit امکان پذیر نیست.
ابتدا یک مثال در مورد تبدیل Implicit بزنیم، در کد زیر یک متغیر از نوع int تعریف شده و سپس مقدار متغیر int را داخل یک متغیر از نوع long میریزیم:
int number1 = 12; long number2 = number1;
کد بالا بدون هیچ مشکلی اجرا میشود و نوع داده int به نوع داده long تبدیل می شود. به این نوع تبدیل Implicit Type Casting گفته می شود. اما کد زیر را در نظر بگیرید:
long number1 = 12; int number2 = number1;
کد بالا اجرا نخواهد شد، زیرا نوع داده long به صورت مستقیم قابل تبدیل به int نیست. برای این مواقع باید از تبدیل Explicit استفاده کرد. زمانی که قصد تبدیل نوعی به نوع دیگر از روش Explicit را داریم، باید قبل از نام متغیر یا مقداری که قرار بر تبدیل آن است، داخل پرانتز نام نوع داده مقصد نوشته شود. برای مثال، در کد زیر ما نوع داده long را به صورت Explicit به int تبدیل می کنیم:
long number1 = 12; int number2 = (int)number1;
همانطور که مشاهده می کنید، قبل از نوشتن نام متغیر number1 در زمان تبدیل، داخل پرانتز نام long نوشته شده، یعنی ما تصمیم داریم مقدار متغیر number1 را به نوع داده long تبدیل کنیم. برای مثال کد زیر مقدار متغیری از نوع decimal را به int تبدیل می کنیم:
decimal number1 = 54.2255m; int number2 = (int) number1;
در تبدیل بالا، دقت کنید که زمان تبدیل متغیر number1 به number2 که تبدیل از نوع decimal به int هست، قسمت اعشاری متغیر number1 از بین می رود.
یک نکته در مورد تبدیل کلاس ها به یکدیگر، اگر به خاطر داشته باشید، در قسمت Inheritance گفتیم که تبدیل از کلاس فرزند به پدر به صورت مستقیم امکان پذیر است، برای مثال، کلاس های زیر را در نظر بگیرید:
public class Base { public int Id { get; set; } } public class Derived : Base { public string Name { get; set; } }
کد زیر بدون مشکل اجرا میشود:
Derived derived = new Derived(); Base @base = derived;
در حقیقت ما متغیر derived که از نوع کلاس فرزند Dervied هست را بدون مشکل و به صورت Implicit به نوع Base تبدیل کردیم، اما برعکس این عملیات، یعنی تبدیل نوع پدر به فرزند به صورت مستقیم امکان پذیر نیست، یعنی در کد بالا اگر بخواهیم متغیر base@ رو به نوع Derived تبدیل کنیم، این کار باید به صورت Explicit انجام شود:
Derived derived = new Derived(); Base @base = derived; Derived castedDervied = (Derived) @base;
کلمات کلیدی checked و unchecked
موقعیتی را فرض کنید که تصمیم داریم متغیری از نوع long را به نوع int تبدیل کنیم. همانطور که می دانید ظرفیت یا بازه عددی نوع long از نوع int بیشتر است، در صورتی که مقدار متغیر long در محدوده بازه عددی نوع int باشد، عملیات تبدیل بدون مشکل انجام می شود، اما فرض کنیم مقدار متغیر long بیشتر از محدوده نوع int باشد، در زمان تبدیل مقداری که داخل متغیر int ما ریخته می شود کاملاً متفاوت با عددی است که در متغیر نوع long است، برای مثال:
long number1 = 5555555555555555555; var number2 = (int)number1;
در کد بالا، پس از اجرای برنامه، مقدار متغیر number2 برابر 623494941- خواهد بود، زیر زمان تبدیل از bit های سر ریز شده مقدار long صرفنظر شده و تنها تعداد bit هایی که در نوع int قابل قرار گرفتن هستند در متغیر نوع int قرار میگیرند، به این مشکل، Overflow شدن گفته می شود. برای حل این مشکل می توان از کلمه کلیدی checked استفاده کرد، شیوه استفاده از این کلمه کلیدی به صورت زیر است:
long number1 = 5555555555555555555; checked { var number2 = (int)number1; }
همانطور که مشاهده می کنید، در کد بالا عملیات تبدیل از long به int در بدنه checked نوشته شده است، با این کار، در صورتی که سرریز اتفاق بیافتد، با پیغام خطای OverflowException برخورد می کنیم، کلمه unchecked دقیقاً شرایطی است که ما بدون نوشتن checked عملیات تبدیل را انجام می دهیم. یعنی سرریز bit ها در زمان تبدیل، در صورت استفاده از کلمه unchecked در نظر گرفته نمی شود.
استفاده از کلاس های Helper برای تبدیل نوع داده ها
ما با دو روش تبدیل انواع داده به یکدیگر آشنا شدیم، روش های Implicit و روش های Explicit، روش دیگری وجود دارد که این روش استفاده از کلاس ها و متدهای Helper می باشد. ما تا اینجا با یکی از این متدها، یعنی متد Parse آشنا شدیم. کلاسی در کتابخانه دات نت وجود دارد با نام Convert که به ما امکان تبدیل انواع داده به یکدیگر را می دهد. برای مثال در کد زیر بوسیله کلاس Convert، نوع رشته به نوع عددی int تبدیل می شود:
string str = "12345"; var number = Convert.ToInt32(str);
کلاس Convert متدهای زیادی دارد، مانند ToInt64، ToByte و ... که می توان از آنها برای تبدیل انواع داده به یکدیگر استفاده کرد. متدهای دیگری نیز در این کلاس وجود دارد که در قسمت پیشرفته با آنها بیشتر آشنا خواهیم شد.
کلمات کلیدی is و as
زمانی که از کلاس ها استفاده می کنیم، نیاز داریم که یک کلاس را به نوع دیگر تبدیل کنیم، برای مثال کد زیر را در نظر بگیرید:
public class Base { } public class Derived1 : Base { } public class Derived2 : Base { }
همانطور که گفتیم، زمانی که می خواهیم متغیری از نوع کلاس پدر را به فرزند تبدیل کنیم، باید به صورت Explicit این کار را انجام دهیم. اما بعضی مواقع ممکن است که عملیات تبدیل امکان پذیر نباشد و پیغام خطا دریافت کنیم. به کد زیر دقت کنید:
Base child = new Derived1(); Derived2 d2 = (Derived2) child;
در کد بالا، عملیات تبدیل به صورت Explicit انجام شده، اما به دلیل اینکه Derived1 قابل تبدیل به Derived2 نیست، پیغام خطا دریافت خواهیم کرد، برای رفع این مشکل می توان از کلمه کلیدی as استفاده کرد. تبدیل بالا را با استفاده از کلمه کلیدی as انجام می دهیم:
Base child = new Derived1(); Derived2 d2 = child as Derived2;
در کد بالا، در صورتی که child قابل تبدیل به نوع Dervied2 باشد، عملیات تبدیل انجام شده و در غیر اینصورت داخل متغیر d2، مقدار null ریخته می شود.
مقدار null، به معنی هیچ است و می توان برای متغیرهایی که از نوع Reference Type هستند، null را استفاده کرد.
اما کلمه کلیدی is چه کاری انجام می دهد؟ کلمه کلیدی is، بررسی می کند که مقدار متغیر سمت چپ، قابل تبدیل به نوع نوشته سمت راست می باشد یا نه، اگر قابل تبدیل باشد، مقدار true و در غیر اینصورت مقدار false را بر میگرداند. مثال:
Base child = new Derived1(); bool isDerived2 = child is Derived2;
در کد بالا، بعد از اجرا متغیر isDerived2 مقدار false خواهد داشت، زیرا مقدار child که از نوع Derived1 است قابل تبدیل به نوع Derived2 نمی باشد.
در این قسمت به بررسی انواع تبدیل ها به یکدیگر پرداختیم و شیوه های مختلف آن را بررسی کردیم، با کلمات کلیدی checked، unchecked، is، as آشنا شدیم و همچنین نحوه استفاده از کلاس Convert را توضیح دادیم. در قسمت بعدی آموزش با نحوه تعریف Cast های دلخواه و همچنین Operator Overloading آشنا می شویم.
منبع:programming.itpro.ir
- ۹۶/۰۳/۰۲