এমনকি আপনি যদি পারে তাদের দেখতে একরকম সমতুল্য হিসাবে তারা উদ্দেশ্য সম্পূর্ণ ভিন্ন করছি। প্রথমে কাস্ট কী তা নির্ধারণ করার চেষ্টা করা যাক:
কাস্টিং হ'ল এক ডেটা টাইপের সত্তাকে অন্যটিতে পরিবর্তনের ক্রিয়া।
এটি সামান্য সামান্য জেনেরিক এবং এটি কোনওভাবে রূপান্তরটির সমতুল্য কারণ একটি castালাই প্রায়শই রূপান্তরটির একই বাক্য গঠন করে থাকে তাই যখন ভাষা দ্বারা কোনও castালাই (অন্তর্নিহিত বা সুস্পষ্ট) অনুমোদিত হয় এবং কখন আপনাকে একটি ব্যবহার করতে হবে তা প্রশ্ন করা উচিত ( আরও) সুস্পষ্ট রূপান্তর?
প্রথমে আমি তাদের মধ্যে একটি সরল রেখা আঁকতে পারি। আনুষ্ঠানিকভাবে (ভাষা বাক্য গঠনের সমতুল্য হলেও) একটি নিক্ষিপ্ত প্রকারটি পরিবর্তিত করবে যখন কোনও রূপান্তরটি মানটি পরিবর্তন করতে পারে / অবশেষে প্রকারের সাথে একসাথে )। রূপান্তর নাও হতে পারে এমন সময় কাস্টও ফেরানো যায়।
এই বিষয়টি বেশ বিস্তৃত তাই কাস্টম কাস্ট অপারেটরদের খেলা থেকে বাদ দিয়ে এটি কিছুটা সংকীর্ণ করার চেষ্টা করি।
অন্তর্ভুক্ত কাস্ট
সি # তে একটি কাস্ট অন্তর্ভুক্ত থাকে যখন আপনি কোনও তথ্য হারাবেন না (দয়া করে নোট করুন যে এই চেকটি প্রকারের সাথে সম্পাদিত হয়েছে তবে তাদের আসল মানগুলির সাথে নয় )।
আদিম ধরণের
উদাহরণ স্বরূপ:
int tinyInteger = 10;
long bigInteger = tinyInteger;
float tinyReal = 10.0f;
double bigReal = tinyReal;
এই ক্যাসেটগুলি অন্তর্নিহিত কারণ রূপান্তরকালে আপনি কোনও তথ্য হারাবেন না (আপনি কেবল প্রকারটি আরও বিস্তৃত করুন)। বিপরীতভাবে অন্তর্নিহিত কাস্টের অনুমতি নেই কারণ তাদের আসল মান নির্বিশেষে (কারণ এগুলি কেবল রান-টাইমে চেক করা যায়), রূপান্তরকালে আপনি কিছু তথ্য হারাতে পারেন। উদাহরণস্বরূপ এই কোডটি সংকলন করবে না কারণ একটিতে doubleএমন কোনও মানটি উপস্থিত থাকতে পারে (এবং প্রকৃতপক্ষে এটি করে) কোনওটির সাথে প্রতিনিধিত্বযোগ্য নয় float:
double bigReal = Double.MaxValue;
float tinyReal = bigReal;
অবজেক্টস
কোনও সামগ্রীর ক্ষেত্রে (একটি পয়েন্টার হিসাবে) কাস্ট সর্বদা জড়িত থাকে যখন সংকলক নিশ্চিত হতে পারে যে উত্সের ধরণটি একটি উদ্ভূত শ্রেণি (বা এটি প্রয়োগ করে) লক্ষ্য শ্রেণীর ধরণ, যেমন:
string text = "123";
IFormattable formattable = text;
NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;
এই ক্ষেত্রে সংকলক জানে যে stringপ্রয়োগগুলি প্রয়োগ করে IFormattableএবং এটি NotSupportedException(থেকে প্রাপ্ত) Exceptionসুতরাং soালাই অন্তর্ভুক্ত। কোনও তথ্যই হারিয়ে যায় না কারণ বস্তুগুলি তাদের ধরণের পরিবর্তন করে না (এটি ভিন্ন ভিন্ন structএবং প্রাচীন প্রকারের সাথে পৃথক কারণ একটি কাস্টের সাহায্যে আপনি অন্য ধরণের একটি নতুন অবজেক্ট তৈরি করেন ), আপনার দৃষ্টিভঙ্গি কী পরিবর্তন করে তাদের করে।
সুস্পষ্ট কাস্ট
কোনও সংকলন স্পষ্ট হয় যখন রূপান্তর সংকলক দ্বারা সুস্পষ্টভাবে সম্পন্ন হয় না এবং তারপরে আপনাকে অবশ্যই কাস্ট অপারেটরটি ব্যবহার করতে পারেন। সাধারণত এটির অর্থ:
- আপনি তথ্য বা ডেটা হারাতে পারেন তাই আপনাকে এটি সম্পর্কে সচেতন হতে হবে।
- রূপান্তরটি ব্যর্থ হতে পারে (কারণ আপনি এক প্রকারের সাথে অন্য রূপে রূপান্তর করতে পারবেন না) সুতরাং, আপনি কী করছেন সে সম্পর্কে আপনাকে অবশ্যই সচেতন হতে হবে।
আদিম ধরণের
রূপান্তরকালে আপনি কিছু ডেটা হারাতে পারেন, উদাহরণস্বরূপ: আদিম ধরণের জন্য একটি স্পষ্ট কাস্ট প্রয়োজন is
double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;
float epsilon = (float)Double.Epsilon;
উভয় উদাহরণে, মানগুলি floatসীমার মধ্যে পড়লেও, আপনি তথ্য হারাবেন (এই ক্ষেত্রে যথাযথ ক্ষেত্রে) সুতরাং রূপান্তরটি সুস্পষ্ট হওয়া উচিত। এখন এটি চেষ্টা করুন:
float max = (float)Double.MaxValue;
এই রূপান্তরটি ব্যর্থ হবে, আবারও, এটি অবশ্যই স্পষ্ট হওয়া উচিত যাতে আপনি এটি সম্পর্কে সচেতন হন এবং আপনি একটি চেক করতে পারেন (উদাহরণস্বরূপ মানটি স্থির থাকে তবে এটি রান-টাইম গণনা বা আই / ও হতে পারে)। আপনার উদাহরণে ফিরে যান:
string text = "123";
double value = (double)text;
এটি সংকলন করবে না কারণ সংকলক পাঠ্যকে সংখ্যায় রূপান্তর করতে পারে না। পাঠ্যটিতে কোনও অক্ষর থাকতে পারে, কেবল সংখ্যা নয় এবং এটি সি # তে খুব বেশি, এমনকি একটি স্পষ্ট কাস্টের জন্যও (তবে এটি অন্য ভাষায় অনুমোদিতও হতে পারে)।
অবজেক্টস
পয়েন্টার থেকে রূপান্তর (বস্তুগুলিতে) ব্যর্থ হতে পারে যদি প্রকারগুলি সম্পর্কিত না হয়, উদাহরণস্বরূপ এই কোডটি সংকলন করবে না (কারণ সংকলক জানেন যে কোনও সম্ভাব্য রূপান্তর নেই):
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";
এই কোডটি সংকলন করবে তবে এটি রান-টাইমে ব্যর্থ হতে পারে (এটি কাস্ট করা বস্তুর কার্যকর ধরণের উপর নির্ভর করে) এর সাথে InvalidCastException:
object obj = GetNextObjectFromInput();
string text = (string)obj;
obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;
রূপান্তর
সুতরাং, অবশেষে, যদি বর্ণগুলি রূপান্তর হয় তবে আমাদের মতো ক্লাসগুলির প্রয়োজন কেন Convert? Convertবাস্তবায়িতকরণ এবং IConvertibleবাস্তবায়ন থেকে আসা সূক্ষ্ম পার্থক্যগুলি উপেক্ষা করা কারণ C # তে আপনি একটি সংকলন দিয়ে সংকলককে বলেছেন:
আমাকে বিশ্বাস করুন, এই টাইপটি হ'ল এমনকি যদি আপনি এটি এখন জানতে না পারেন তবে আমাকে এটি করতে দিন এবং আপনি দেখতে পাবেন।
-অর-
চিন্তা করবেন না, এই রূপান্তরটিতে কিছু হারিয়ে যাবে কিনা সে বিষয়ে আমি চিন্তা করি না।
অন্য যে কোনও কিছুর জন্য আরও সুস্পষ্ট অপারেশন প্রয়োজন ( সহজ ক্যাসেটগুলির জড়িত সম্পর্কে চিন্তা করুন , এজন্য সি ++ তাদের জন্য দীর্ঘ, ভার্বোস এবং স্পষ্ট স্পষ্ট বাক্য গঠন করেছেন)। এটিতে একটি জটিল অপারেশন জড়িত থাকতে পারে (কারণ string-> doubleরূপান্তরকরণের জন্য পার্সিংয়ের প্রয়োজন হবে)। stringউদাহরণস্বরূপ, রূপান্তরকরণ সর্বদা সম্ভব ( ToString()পদ্ধতির মাধ্যমে ) তবে এটির অর্থ যা আপনি প্রত্যাশা করেন তার চেয়ে আলাদা কিছু হতে পারে তাই এটি অবশ্যই একটি অভিনেতার চেয়ে আরও স্পষ্ট হওয়া উচিত ( আপনি যত বেশি লিখবেন, আপনি কী করছেন সে সম্পর্কে আপনি আরও ভাবেন )।
এই রূপান্তরটি বস্তুর ভিতরে করা যেতে পারে (এর জন্য পরিচিত আইএল নির্দেশাবলী ব্যবহার করে), কাস্টম রূপান্তর অপারেটরগুলি (castালতে শ্রেণিতে সংজ্ঞায়িত) বা আরও জটিল প্রক্রিয়া ( TypeConverterগুলি বা শ্রেণীর পদ্ধতিগুলি উদাহরণস্বরূপ) ব্যবহার করে করা যেতে পারে। কী হবে তা আপনি সচেতন নন তবে আপনি সচেতন হন যে এটি ব্যর্থ হতে পারে (এ কারণেই আইএমও যখন আরও নিয়ন্ত্রিত রূপান্তর সম্ভব হয় তখন এটি ব্যবহার করা উচিত)। আপনার ক্ষেত্রে রূপান্তরটি কেবল stringএকটি উত্পাদন করার জন্য পার্স করবে double:
double value = Double.Parse(aStringVariable);
অবশ্যই এটি ব্যর্থ হতে পারে যদি আপনি এটি করেন তবে আপনার সর্বদা এটি ব্যতিক্রম ( FormatException) ছোঁড়া উচিত should এটি এখানে বিষয়বস্তুর বাইরে নয় তবে যখন একটি TryParseউপলব্ধ থাকে তখন আপনার এটি ব্যবহার করা উচিত (কারণ শব্দার্থগতভাবে আপনি বলেন এটি একটি সংখ্যা নাও হতে পারে এবং এটি আরও দ্রুত ... ব্যর্থ হওয়ার জন্য)।
.NET- এ রূপান্তরগুলি প্রচুর জায়গা থেকে, TypeConverterব্যবহারকারীর সংজ্ঞায়িত রূপান্তর অপারেটরগুলির সাথে অন্তর্নিহিত / স্পষ্ট বর্ণের ক্যাসেটগুলি থেকে প্রয়োগ হতে পারেIConvertible কাস্ট্রস, পদ্ধতি এবং পার্সিংয়ের পদ্ধতি (আমি কি কিছু ভুলে গেছি?) থেকে আসতে পারে। তাদের সম্পর্কে আরও বিশদ জানতে এমএসডিএন এ একবার দেখুন।
এই দীর্ঘ উত্তরটি ব্যবহারকারীর সংজ্ঞায়িত রূপান্তর অপারেটরদের সম্পর্কে মাত্র কয়েকটি শব্দ শেষ করতে। প্রোগ্রামারকে এক প্রকারের থেকে অন্য প্রকারে রূপান্তর করতে একটি কাস্ট ব্যবহার করতে দেওয়া এটি কেবল চিনি । এটি একটি শ্রেণীর অভ্যন্তরের একটি পদ্ধতি (যা নিক্ষিপ্ত হবে) সে বলে যে "আরে, যদি সে এই ধরণেরটিকে এই ধরণের রূপান্তর করতে চায় তবে আমি এটি করতে পারি"। উদাহরণ স্বরূপ:
float? maybe = 10;
float sure1 = (float)maybe;
float sure2 = maybe.Value;
এই ক্ষেত্রে এটি সুস্পষ্ট কারণ এটি ব্যর্থ হতে পারে তবে এটি বাস্তবায়নের জন্য দেওয়া হয় (এমনকি যদি এ সম্পর্কে গাইডলাইন থাকে তবে)। আপনি যেমন একটি কাস্টম স্ট্রিং ক্লাস লিখুন তা কল্পনা করুন:
EasyString text = "123";
double value = (string)text;
আপনার প্রয়োগে আপনি "প্রোগ্রামারের জীবনকে সহজ করার" সিদ্ধান্ত নিতে পারেন এবং এই রূপান্তরটি একটি কাস্টের মাধ্যমে প্রকাশ করতে পারেন (মনে রাখবেন এটি কম লেখার জন্য একটি শর্টকাট)) কিছু ভাষা এমনকি এটি অনুমতি দিতে পারে:
double value = "123";
কোনও প্রকারের মধ্যে অন্তর্নিহিত রূপান্তরকে মঞ্জুরি দেওয়া হচ্ছে (চেক রান-টাইমে সম্পন্ন হবে)। যথাযথ বিকল্পগুলির সাহায্যে এটি করা যেতে পারে, উদাহরণস্বরূপ, ভিবি.এনইটি তে। এটি কেবল একটি ভিন্ন দর্শন।
আমি তাদের সাথে কি করতে পারি?
সুতরাং চূড়ান্ত প্রশ্ন হ'ল কখন আপনার এক বা অন্য ব্যবহার করা উচিত। আসুন দেখুন কখন আপনি একটি সুস্পষ্ট কাস্ট ব্যবহার করতে পারেন:
- বেস ধরণের মধ্যে রূপান্তর।
objectঅন্য যে কোনও ধরণের রূপান্তর (এতে আনবক্সিংও অন্তর্ভুক্ত থাকতে পারে)।
- উত্পন্ন শ্রেণি থেকে একটি বেস শ্রেণিতে রূপান্তর (বা প্রয়োগিত ইন্টারফেসে)।
- কাস্টম রূপান্তর অপারেটরগুলির মাধ্যমে এক ধরণের থেকে অন্য ধরণের রূপান্তর।
কেবলমাত্র প্রথম রূপান্তরটিই এর সাথে করা যায় Convertআপনার পছন্দ নেই এমন অন্যদের জন্য এবং আপনার একটি স্পষ্ট কাস্ট ব্যবহার করা দরকার।
আপনি এখন কখন ব্যবহার করতে পারবেন তা দেখুন Convert:
- যে কোনও বেস টাইপ থেকে অন্য বেস টাইপের রূপান্তর (কিছু সীমাবদ্ধতার সাথে দেখুন, এমএসডিএন দেখুন )।
- যে কোনও প্রকার রূপান্তরগুলি যা
IConvertibleঅন্য কোনও (সমর্থিত) প্রকারে প্রয়োগ করে।
- স্ট্রেনে / থেকে একটি
byteঅ্যারে থেকে / রূপান্তর ।
সিদ্ধান্তে
আইএমও Convertপ্রতিটি বার ব্যবহার করা উচিত যখন আপনি জানেন যে কোনও রূপান্তর ব্যর্থ হতে পারে (বিন্যাসের কারণে, ব্যাপ্তির কারণে বা এটি অসমর্থিত হতে পারে), এমনকি যদি একই রূপান্তর কোনও কাস্টের মাধ্যমে করা যায় (অন্য কোনও কিছু উপলব্ধ না থাকে)। এটি আপনার উদ্দেশ্যটি কী আপনার কোডটি পড়বে তা পরিষ্কার করে দেয় এবং কে এটি ব্যর্থ হতে পারে (ডিবাগ সরলকরণ)
অন্য যে কোনও কিছুর জন্য আপনার প্রয়োজন cast আপনার উদাহরণে থেকে একটি রূপান্তর stringকরতে doubleকিছু যে (পাঠ্য ব্যবহারকারী থেকে আসে, বিশেষ করে যদি) খুব প্রায়ই একটি ব্যবহার উদাহরণস্বরূপ ব্যর্থ হবে যাতে আপনি অনেক স্পষ্ট সম্ভব (পরন্তু আপনি এটা উপর আরো বেশি নিয়ন্ত্রণ পাবেন) যেমন করা উচিত হয় TryParseপদ্ধতি।
সম্পাদনা: তাদের মধ্যে পার্থক্য কী?
হালনাগাদ প্রশ্ন অনুসারে এবং আমি যা লিখেছিলাম তা অনুসারে ( আপনি যখন ব্যবহার করতে পারেন / Convertতুলতে পারেন তুলনায় আপনি যখন কাস্ট ব্যবহার করতে পারেন ) তখন তাদের মধ্যে পার্থক্য থাকলে তা স্পষ্ট করার শেষ পয়েন্টটি রয়েছে (তদ্ব্যতীত Convertব্যবহার IConvertibleএবংIFormattable ইন্টারফেসগুলি যাতে এটি অপারেশন সম্পাদন করতে পারে কাস্টের সাথে অনুমোদিত নয়)।
সংক্ষিপ্ত উত্তর হ্যাঁ, তারা ভিন্ন আচরণ করে । আমি Convertসহকারী পদ্ধতিগুলির ক্লাসের মতো ক্লাসটি দেখি তাই প্রায়শই এটি কিছু উপকার বা কিছুটা ভিন্ন আচরণ সরবরাহ করে। উদাহরণ স্বরূপ:
double real = 1.6;
int castedInteger = (int)real;
int convertedInteger = Convert.ToInt32(real);
বেশ আলাদা, তাই না? কাস্টটি কেটে যায় (এটি আমরা সকলেই প্রত্যাশা করি) তবে Convertনিকটতম পূর্ণসংখ্যার জন্য একটি বৃত্তাকার সঞ্চালন করে (এবং আপনি যদি এটি অবগত না হন তবে এটি আশা করা যায় না)। প্রতিটি রূপান্তর পদ্ধতি পার্থক্যের পরিচয় দেয় যাতে একটি সাধারণ নিয়ম প্রয়োগ করা যায় না এবং তাদের কেস অনুসারে কেস দেখাতে হবে ... প্রতিটি অন্যান্য ধরণের রূপান্তর করার জন্য 19 টি বেস ধরণের ... তালিকা এমএসডিএন কেসের সাথে পরামর্শ করার জন্য আরও দীর্ঘতর হতে পারে কেস!