ویرگول
ورودثبت نام
فرشید عزیزی
فرشید عزیزیSoftware Engineer
فرشید عزیزی
فرشید عزیزی
خواندن ۷ دقیقه·۲ سال پیش

دوره آموزشی #C-قسمت 24 - Type Casting

دوره آموزشی #C-قسمت 23 - virtual modifier

مقدمه ای بر casting :

سی شارپ یک زبان برنامه نویسی با statically-typed است. یعنی بعد از اینکه یک متغیر را اعلان کردید،
نمی توانید آن را دوباره اعلان کنید. همچنین، نمی‌توانید مقدار دیگری را به متغیر اختصاص دهید، مگر اینکه آن نوع به طور ضمنی(implicitly) با نوع متغیر سازگار باشد.برای مثال، string را نمی توان به طور ضمنی به int تبدیل کرد. با توجه به مثال زیر، پس از اینکه i را به عنوان int اعلان کردید، نمی توانید رشته "Hello" را به آن اختصاص دهید،

int i; i = 'Hello' // error CS0029: Cannot implicitly convert type 'string' to 'int'
به تبدیل انواع داده به یکدیگر Type Casting می گویند.

انواع type casting:

  • تبدیل نوع Implicitly(upcast)
  • تبدیل نوعExplicitly(downcast)
  • تبدیل نوع helper classes

تبدیل نوع Implicitly(upcast) :

هیچ syntax خاصی مورد نیاز نیست زیرا تبدیل همیشه با موفقیت انجام می شود و هیچ داده ای از بین
نمی رود.

برای built-in numeric types، زمانی می‌توان تبدیل ضمنی/Implicitly انجام داد که مقدار ذخیره‌سازی شده بتواند بدون بریده شدن یا گرد شدن در متغیر قرار گیرد. به عنوان مثال، یک متغیر از نوع long (عدد صحیح 64 بیتی) می تواند هر مقداری را که یک int (عدد صحیح 32 بیتی) می تواند ذخیره کند، ذخیره کند.

تبدیل type کوچکتر به type بزرگتر را Implicitly(upcast) می گویند.


برای reference types، تبدیل ضمنی /Implicitly همیشه از یک کلاس به هر یک از کلاس ها یا اینترفیس های پایه مستقیم یا غیرمستقیم آن وجود دارد. هیچ نحو خاصی لازم نیست زیرا یک کلاس مشتق شده همیشه شامل تمام اعضای یک کلاس پایه است.

Derived d = new Derived(); // Always OK. Base b = d;


تبدیل نوعExplicitly(downcast) :

با این حال، اگر یک تبدیل با خطر از دست دادن اطلاعات انجام شود، کامپایلر از شما می خواهد که یک تبدیل صریح/Explicitly را انجام دهید. این نوع تبدیل راهی برای اطلاع صریح به کامپایلر است که قصد دارید تبدیل را انجام دهید و از اینکه ممکن است داده‌ها از بین برود یا در زمان اجرا شکست بخورد، آگاه هستید. برای انجام Cast، نوع ارسالی را در پرانتز در مقابل مقدار یا متغیری که باید تبدیل شود، مشخص کنید.

(T)E

عبارت cast به صراحت نتیجه عبارت Eرا به نوع (T) تبدیل می کند. اگر هیچ تبدیل صریحی از نوع E به نوع T وجود نداشته باشد، کامپایلر یک خطا ایجاد می کند.
مثال :

class Test { static void Main() { double x = 1234.7; int a; // Cast double to int. a = (int)x; System.Console.WriteLine(a); } } // Output: 1234

برای reference types، در صورتی که نیاز به تبدیل از نوع پایه به نوع مشتق شده دارید، یک explicit cast مورد نیاز است:

// Create a new derived type. Giraffe g = new Giraffe(); // Implicit conversion to base type is safe. Animal a = g; // Explicit conversion is required to cast back // to derived type. Note: This will compile but will // throw an exception at run time if the right-side // object is not in fact a Giraffe. Giraffe g2 = (Giraffe)a;

یک عملیات cast بین reference typeها، run-time type شی زیرین را تغییر نمی دهد. فقط نوع مقداری را که به عنوان reference برای آن شیء استفاده می شود تغییر می دهد.

در برخی از تبدیل‌های reference type، کامپایلر نمی‌تواند تعیین کند که آیا یک Cast معتبر خواهد بود یا خیر. ممکن است عملیات castی که به درستی کامپایل می شود در زمان اجرا با شکست مواجه شود.

بنابراین بهتر است از قبل سازگاری را آزمایش کنید.

سی شارپ عملگر is و as را برای آزمایش اینکه آیا یک مقدار از نوع خاصی است یا خیر ارائه می کند.

عملگر as یک downcast را انجام می دهد که به جای اینکه در صورت شکست downcast یک استثنا ایجاد کند، null ارزیابی می شود. این به شما امکان می دهد متعاقباً بررسی کنید که آیا نتیجه downcast برابر null است یا خیر. مثلا:

var employee = new Employee() { Name = 'reza mohamadi', JobTitle = 'C# Developer' }; Person person = employee;// upcast Candidate candidate = person as Candidate; if (candidate != null) { Console.WriteLine(candidate.Name); }

عملگر is، هم همانند عملگر as می باشد با این تفاوت که اگر قابل تبدیل باشد، مقدار true و در غیر اینصورت مقدار false را بر میگرداند.

خلاصه اینکه :

  • یک object reference می تواند به طور implicitly به یک base class reference آپکست شود. یک upcast همیشه موفق است.
  • یک object reference نیز می تواند به طور explicitly به یک subclass reference دانکست یابد. یک downcast فقط در صورتی موفق می شود که شی با type آن سازگار باشد.
  • از عملگر as برای اجرای downcast استفاده می کنیم که به جای ایجاد یک throwing exception در زمان اجرا، به null ارزیابی می شود.


تبدیل نوع helper classes :

برای تبدیل بین انواع غیر سازگار، کلاسی در کتابخانه دات نت وجود دارد با نام Convert که به ما امکان تبدیل انواع داده به یکدیگر را می دهد. برای مثال در کد زیر بوسیله کلاس Convert، نوع رشته به نوع عددی int تبدیل می شود:

string str = '1234567890' var number = Convert.ToInt32(str);

کلاس Convert بسته به مقدار base type در زمان اجرا و base type هدف، می تواند یکی از پنج نتیجه را ایجاد کند. این پنج نتیجه عبارتند از:

  • بدون تبدیل(No conversion): این زمانی اتفاق می افتد که سعی شود از یک نوع به خودش تبدیل شود (مثلاً با فراخوانی Convert.ToInt32(Int32) در حالی که base type هدف همان Int32 است).
  • یک InvalidCastException: این زمانی اتفاق می افتد که یک تبدیل خاص پشتیبانی نمی شود. یک InvalidCastException برای تبدیل‌های زیر ایجاد می‌شود:

Conversions from Char to Boolean, Single, Double, Decimal, or DateTime.

Conversions from Boolean, Single, Double, Decimal, or DateTime to Char.

Conversions from DateTime to any other type except String.

Conversions from any other type, except String, to DateTime.

  • یک FormatException : این زمانی اتفاق می‌افتد که تلاش برای تبدیل یک مقدار string به هر نوع پایه دیگر با شکست مواجه شود زیرا رشته در قالب مناسب نیست. استثنا برای تبدیل های زیر ایجاد می شود:

A string to be converted to a Boolean value does not equal Boolean.TrueString or Boolean.FalseString.

A string to be converted to a Char value consists of multiple characters.

A string to be converted to any numeric type is not recognized as a valid number.

A string to be converted to a DateTime is not recognized as a valid date and time value

  • یک تبدیل موفق(successful conversion) : برای تبدیل‌های بین دو نوع پایه مختلف که منجر به از دست دادن داده‌ها نمی‌شوند و متد مقداری از نوع پایه هدف را برمی‌گرداند.
  • یک OverflowException : این زمانی اتفاق می‌افتد که یک تبدیل منجر به از دست رفتن داده شود. برای مثال، تلاش برای تبدیل یک نمونه Int32 که مقدار آن 10000 است به یک نوع بایت، یک OverflowException ایجاد می کند زیرا 10000 خارج از محدوده نوع داده بایت است.
اگر تبدیل یک نوع عددی منجر به از دست دادن دقت شود (یعنی از دست دادن برخی از ارقام کم اهمیت) استثنایی ایجاد نخواهد شد.


یکی دیگر از انواع helper classes برای تبدیل رشته به عدد فراخوانی متد فراخوانی متد Parse یا TryParse است.

متد Parse عدد تبدیل شده را برمی گرداند. متد TryParse یک مقدار بولی برمی‌گرداند که نشان می‌دهد آیا تبدیل موفق بوده است یا خیر، و عدد تبدیل‌شده را در یک پارامتر out برمی‌گرداند.

متدهای Parse و TryParse فضای سفید را در ابتدا و انتهای رشته نادیده می‌گیرند، اما همه کاراکترهای دیگر باید کاراکترهایی باشند که نوع عددی مناسب را تشکیل می‌دهند (int، long، ulong، float، decimal و غیره). هر فضای خالی در رشته ای که عدد را تشکیل می دهد باعث خطا می شود. برای مثال، می‌توانید از decimal.TryParse برای استخراج «10»، «10.3»، یا «10» استفاده کنید، اما نمی‌توانید از این متد برای استخراج 10 از «10X»، «1 0» استفاده کنید (به فضای تعبیه‌شده توجه کنید) ، "10.3" (به فضای تعبیه شده توجه کنید)، "10e1" (float.TryParse در اینجا کار می کند).

شما می توانید با فراخوانی متد String.IsNullOrEmpty، وجود یک رشته Empty یا Null را بررسی کنید.

متد ()Parse

قبل از استفاده از ()Parse، باید مطمئن شویم که تبدیل با موفقیت انجام می شود. در غیر این صورت برنامه از کار می افتد.

برای تبدیل رشته به هر نوع داده ای، از syntax زیر استفاده می کنیم:

data_type.Parse(string);

مثال :

string var_string = '4.5' Console.WriteLine(int.Parse('4') + 3); Console.WriteLine(float.Parse(var_string) + 4.4f); //output : 7 8.9


متد ()TryParse :

متد ()TryParse نوع داده رشته را به نوع داده دیگری تبدیل می کند. مقدار True یا False را بر اساس تبدیل موفق یا ناموفق برمی گرداند. ()TryParse یک رویکرد امن تر است زیرا اجرای برنامه را خاتمه نمی دهد.

data_type.TryParse(string, out output_variable);

متد ()TryParse دو پارامتر دریافت می کند. اولین پارامتر رشته ای است که باید تبدیل شود. پارامتر دوم متغیری است که مقدار تبدیل شده را ذخیره می کند. کلمه کلیدی out قبل از پارامتر دوم استفاده می شود.

بیشتر بخوانید : دوره آموزشی #C-قسمت 25 - Abstract Class

بیشتر بخوانید : نقشه راه توسعه دهندگان Asp.NET Core

https://zarinp.al/farshidazizi

دوره آموزشی
۲
۰
فرشید عزیزی
فرشید عزیزی
Software Engineer
شاید از این پست‌ها خوشتان بیاید