Ingালাই এবং কনভার্ট.টো () পদ্ধতি ব্যবহারের মধ্যে পার্থক্য


91

আমার একটি ফাংশন রয়েছে যা মানগুলিকে কাস্ট doubleকরে string

string variable = "5.00"; 

double varDouble = (double)variable;

একটি কোড পরিবর্তন চেক ইন ছিল এবং প্রকল্পটি ত্রুটিটি সহ তৈরি করে: System.InvalidCastException: Specified cast is not valid.

তবে, নিম্নলিখিতগুলি করার পরে ...

string variable = "5.00"; 

double varDouble = Convert.ToDouble(variable);

... প্রকল্পটি কোনও ত্রুটি ছাড়াই তৈরি করে।

কাস্টিং এবং Convert.To()পদ্ধতিটি ব্যবহারের মধ্যে পার্থক্য কী ? Ingালাই কেন একটি নিক্ষেপ করে না Exceptionএবং ব্যবহার Convert.To()করে না?

c#  casting 


6
কোনও রেফারেন্সযুক্ত প্রশ্নের ক্ষেত্রে , ওপি কখন কাস্ট ব্যবহার করবে বা রূপান্তর করবে জিজ্ঞাসা করবে এবং স্বীকৃত উত্তরে বলা হয়েছে, "আপনি যেই ব্যবহার করেন না কেন এটি সত্যিই পছন্দের বিষয়।" আমি একটি castালাই বনাম একটি রূপান্তর মধ্যে পার্থক্য জিজ্ঞাসা করছি। আমার মতে, নীচের উত্তরগুলি (কুডোস এসও!) বনাম "এই বা এটি পছন্দ হিসাবে ব্যবহার করা" সম্পর্কিত পার্থক্য সম্পর্কে আরও বিশদ সরবরাহ করে ... এবং এই বিবরণটি সংক্ষেপে আরও বেশি বুদ্ধিমান পছন্দ করতে ব্যবহার করা যেতে পারে।

@ এডমাস্টারমাইন্ড 29 প্রোগ্রামিং প্রসঙ্গে "x এবং y এর মধ্যে পার্থক্য কী" এবং "কখন x এবং y ব্যবহার করবেন" এর মধ্যে খুব বেশি পার্থক্য নেই। দু'জনেই পরস্পর জবাব দেয়।
নওফাল

4
প্রায় 3 বছর পরে, এমনটি দেখা যায় না যে এই ক্ষেত্রে একজন পরস্পর জবাব দেয়। প্রশ্ন: "এক্স এবং ওয়াইয়ের মধ্যে পার্থক্য কী?" উ: "আপনি যে কোনওটি ব্যবহার করুন এটি সত্যিই পছন্দের বিষয়" " খুব দরকারী না।

কারও কাছে প্রত্যক্ষ উত্তর নেই বলে মনে হয় যার পক্ষে সেরা অভিনয় করাও এই প্রশ্নের একটি অংশ, আমার অভিজ্ঞতা থেকে আমি দেখছি কাস্ট বিশেষত কলামের মানগুলি অর্জনের ক্ষেত্রে ভাল .. .. (অন্তর্) ডেটাটেবল R সারণী [0] [0], যদি আমরা এর 100%
ইনটি

উত্তর:


127

এমনকি আপনি যদি পারে তাদের দেখতে একরকম সমতুল্য হিসাবে তারা উদ্দেশ্য সম্পূর্ণ ভিন্ন করছি। প্রথমে কাস্ট কী তা নির্ধারণ করার চেষ্টা করা যাক:

কাস্টিং হ'ল এক ডেটা টাইপের সত্তাকে অন্যটিতে পরিবর্তনের ক্রিয়া।

এটি সামান্য সামান্য জেনেরিক এবং এটি কোনওভাবে রূপান্তরটির সমতুল্য কারণ একটি castালাই প্রায়শই রূপান্তরটির একই বাক্য গঠন করে থাকে তাই যখন ভাষা দ্বারা কোনও castালাই (অন্তর্নিহিত বা সুস্পষ্ট) অনুমোদিত হয় এবং কখন আপনাকে একটি ব্যবহার করতে হবে তা প্রশ্ন করা উচিত ( আরও) সুস্পষ্ট রূপান্তর?

প্রথমে আমি তাদের মধ্যে একটি সরল রেখা আঁকতে পারি। আনুষ্ঠানিকভাবে (ভাষা বাক্য গঠনের সমতুল্য হলেও) একটি নিক্ষিপ্ত প্রকারটি পরিবর্তিত করবে যখন কোনও রূপান্তরটি মানটি পরিবর্তন করতে পারে / অবশেষে প্রকারের সাথে একসাথে )। রূপান্তর নাও হতে পারে এমন সময় কাস্টও ফেরানো যায়।

এই বিষয়টি বেশ বিস্তৃত তাই কাস্টম কাস্ট অপারেটরদের খেলা থেকে বাদ দিয়ে এটি কিছুটা সংকীর্ণ করার চেষ্টা করি।

অন্তর্ভুক্ত কাস্ট

সি # তে একটি কাস্ট অন্তর্ভুক্ত থাকে যখন আপনি কোনও তথ্য হারাবেন না (দয়া করে নোট করুন যে এই চেকটি প্রকারের সাথে সম্পাদিত হয়েছে তবে তাদের আসল মানগুলির সাথে নয় )।

আদিম ধরণের

উদাহরণ স্বরূপ:

int tinyInteger = 10;
long bigInteger = tinyInteger;

float tinyReal = 10.0f;
double bigReal = tinyReal;

এই ক্যাসেটগুলি অন্তর্নিহিত কারণ রূপান্তরকালে আপনি কোনও তথ্য হারাবেন না (আপনি কেবল প্রকারটি আরও বিস্তৃত করুন)। বিপরীতভাবে অন্তর্নিহিত কাস্টের অনুমতি নেই কারণ তাদের আসল মান নির্বিশেষে (কারণ এগুলি কেবল রান-টাইমে চেক করা যায়), রূপান্তরকালে আপনি কিছু তথ্য হারাতে পারেন। উদাহরণস্বরূপ এই কোডটি সংকলন করবে না কারণ একটিতে doubleএমন কোনও মানটি উপস্থিত থাকতে পারে (এবং প্রকৃতপক্ষে এটি করে) কোনওটির সাথে প্রতিনিধিত্বযোগ্য নয় float:

// won't compile!
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;

এই রূপান্তরটি ব্যর্থ হবে, আবারও, এটি অবশ্যই স্পষ্ট হওয়া উচিত যাতে আপনি এটি সম্পর্কে সচেতন হন এবং আপনি একটি চেক করতে পারেন (উদাহরণস্বরূপ মানটি স্থির থাকে তবে এটি রান-টাইম গণনা বা আই / ও হতে পারে)। আপনার উদাহরণে ফিরে যান:

// won't compile!
string text = "123";
double value = (double)text;

এটি সংকলন করবে না কারণ সংকলক পাঠ্যকে সংখ্যায় রূপান্তর করতে পারে না। পাঠ্যটিতে কোনও অক্ষর থাকতে পারে, কেবল সংখ্যা নয় এবং এটি সি # তে খুব বেশি, এমনকি একটি স্পষ্ট কাস্টের জন্যও (তবে এটি অন্য ভাষায় অনুমোদিতও হতে পারে)।

অবজেক্টস

পয়েন্টার থেকে রূপান্তর (বস্তুগুলিতে) ব্যর্থ হতে পারে যদি প্রকারগুলি সম্পর্কিত না হয়, উদাহরণস্বরূপ এই কোডটি সংকলন করবে না (কারণ সংকলক জানেন যে কোনও সম্ভাব্য রূপান্তর নেই):

// won't compile!    
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; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast

এই ক্ষেত্রে এটি সুস্পষ্ট কারণ এটি ব্যর্থ হতে পারে তবে এটি বাস্তবায়নের জন্য দেওয়া হয় (এমনকি যদি এ সম্পর্কে গাইডলাইন থাকে তবে)। আপনি যেমন একটি কাস্টম স্ট্রিং ক্লাস লিখুন তা কল্পনা করুন:

EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double

আপনার প্রয়োগে আপনি "প্রোগ্রামারের জীবনকে সহজ করার" সিদ্ধান্ত নিতে পারেন এবং এই রূপান্তরটি একটি কাস্টের মাধ্যমে প্রকাশ করতে পারেন (মনে রাখবেন এটি কম লেখার জন্য একটি শর্টকাট)) কিছু ভাষা এমনকি এটি অনুমতি দিতে পারে:

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; // 1
int convertedInteger = Convert.ToInt32(real); // 2

বেশ আলাদা, তাই না? কাস্টটি কেটে যায় (এটি আমরা সকলেই প্রত্যাশা করি) তবে Convertনিকটতম পূর্ণসংখ্যার জন্য একটি বৃত্তাকার সঞ্চালন করে (এবং আপনি যদি এটি অবগত না হন তবে এটি আশা করা যায় না)। প্রতিটি রূপান্তর পদ্ধতি পার্থক্যের পরিচয় দেয় যাতে একটি সাধারণ নিয়ম প্রয়োগ করা যায় না এবং তাদের কেস অনুসারে কেস দেখাতে হবে ... প্রতিটি অন্যান্য ধরণের রূপান্তর করার জন্য 19 টি বেস ধরণের ... তালিকা এমএসডিএন কেসের সাথে পরামর্শ করার জন্য আরও দীর্ঘতর হতে পারে কেস!


আমি জিজ্ঞাসা করার জন্য প্রশ্ন পরিবর্তন করেছি Difference between casting and using the Convert.To() method,। অন্যথায়, খুব ব্যাপক উত্তর। (আমি আশা করি আমার প্রশ্নটি আবার খোলা আছে ...)

@ এডমাস্টারমাইন্ড 29 আমি প্রশ্নটি সামান্যই সম্পাদনা করেছি, বিষয়টি দীর্ঘ উত্তর দেওয়ার জন্য এমনকি (300+ সম্ভাব্য রূপান্তর তালিকার পক্ষে) খুব দীর্ঘ। রূপান্তরটি সুবিধার (বা কেবল অপ্রত্যাশিত আচরণ?) যোগ করে কেবল বনাম কাস্ট নয়, বনাম "প্লেইন" আইকনভার্টেবল এবং আইফর্ম্যাট্যাটেবল ইন্টারফেসও।
অ্যাড্রিয়ানো রেপিটি

সি থেকে ধার করা ধারণাটি আমি পছন্দ doubleকরি না যে মানগুলি পুরো সংখ্যার প্রতিনিধিত্ব করে না সেগুলিতে "রূপান্তরযোগ্য" হওয়া উচিত int। একটি ঢালাই ক্ষেত্রে যেখানে যেমন এক পুনরুদ্ধার করছে যথাযথ দৃষ্টান্ত মনে হবে Int32একটি থেকে মানগুলি double[]যা বাস্তব সংখ্যা এবং একটি মিশ্রণ ঝুলিতে Int32মান যে রূপান্তরিত করা হয়েছে double[যে representable নয় একটি মান রূপান্তর করার একটি প্রয়াস অবিকল মধ্যে int32একটি অপ্রত্যাশিত অবস্থার ইঙ্গিত হবে এবং একটি ব্যতিক্রম ট্রিগার করা উচিত], তবে আমি মনে করব যে যখন কেউ ক্ষয়িষ্ণু রূপান্তর চায় তখন তার ফর্মটি সম্পর্কে নির্দিষ্ট হওয়া উচিত।
সুপারক্যাট

4
আর একটি পার্থক্য হ'ল বস্তু থেকে আদিম ধরণের। উদাহরণস্বরূপobject o = 123; var l = Convert.ToInt64(o); var i = (long) (int) o; var f = (long) o // InvalidCastException
ইয়ে শি শি

4
@ rory.ap এটি একটি গুরুত্বপূর্ণ বিষয়। না, আনুষ্ঠানিকভাবে এটি cast ালাই নয় ( float-> int) তবে জবরদস্তি । একটি কাস্ট উদাহরণস্বরূপ হতে পারে DerivedClass-> BaseClass। এটি বিভ্রান্তিকর কারণ সি # তে আমরা উভয়ের জন্য একই শব্দ (এবং অপারেটর) ব্যবহার করি তবে সেগুলি আসলে স্বতন্ত্র জিনিস। তাদের মধ্যে পার্থক্য করার একটি আনুষ্ঠানিক সংজ্ঞা আমার লেখার চেয়ে কিছুটা জটিল।
অ্যাড্রিয়ানো রেপিটি

13

Castালাই সংকলককে বলার একটি উপায়, "আমি জানি যে আপনি এই ভেরিয়েবলটি একটি বার বলে মনে করেন, তবে আমি আপনার চেয়ে আরও বেশি কিছু জানতে পেরেছি; বস্তুটি আসলে একটি ফু, তাই আমাকে এটিকে এমনভাবে আচরণ করা উচিত যেন এটি কোনও ফুও ছিল এখন." তারপরে, রানটাইমের সময়, যদি সত্যিকারের বস্তুটি সত্যিই একটি ফু হিসাবে দেখা দেয় তবে আপনার কোডটি কাজ করে, যদি এটি সক্রিয় হয় যে অবজেক্টটি কোনওভাবেই ফু ছিল না, তবে আপনি একটি ব্যতিক্রম পান। (বিশেষত একটি System.InvalidCastException।)

অন্যদিকে রূপান্তর হ'ল বলার একটি উপায়, "যদি আপনি আমাকে বার টাইপ টাইপ করে থাকেন তবে আমি একটি নতুন Foo অবজেক্ট তৈরি করতে পারি যা সেই বারের অবজেক্টের মধ্যে উপস্থিত রয়েছে I আমি আসল বস্তুটি পরিবর্তন করব না, এটি জিতেছে ' মূল বস্তুকে অন্যরকম আচরণ করবে না, এটি নতুন কিছু তৈরি করবে যা অন্য কিছু মূল্যের উপর ভিত্তি করে it এটি কীভাবে এটি করবে এটি কিছু হতে পারে Convert.ToDoubleit এটির ক্ষেত্রে ফোনটি শেষ হবেDouble.Parseকোন ধরণের স্ট্রিংগুলি সংখ্যাসূচক মানকে উপস্থাপন করে তা নির্ধারণের জন্য যার মধ্যে সমস্ত ধরণের জটিল যুক্তি রয়েছে। আপনি নিজের রূপান্তর পদ্ধতিটি লিখতে পারেন যা স্ট্রিংগুলিকে দ্বিগুণ করে ম্যাপ করেছে (সম্ভবত কিছু সংখ্যক প্রদর্শন করার জন্য সম্পূর্ণ ভিন্ন কনভেনশনকে সমর্থন করতে যেমন রোমান সংখ্যাসমূহ বা যে কোনও কিছু)। কোনও রূপান্তর কিছু করতে পারে তবে ধারণাটি হ'ল আপনি সত্যই কম্পাইলারকে আপনার জন্য কিছু করতে বলছেন না; আপনি নতুন কোডটি কীভাবে তৈরি করবেন তা নির্ধারণের জন্য কোড লিখছেন আপনিই কারণ আপনার সংযোজনকারী সংকলক, কীভাবে মানচিত্র করবেন তা জানার উপায় নেই (উদাহরণস্বরূপ) একটিstring একটি থেকে double

সুতরাং, আপনি কখন রূপান্তর করবেন এবং কখন আপনি নিক্ষেপ করবেন? উভয় ক্ষেত্রেই আমাদের একটি প্রকারের কিছু ভেরিয়েবল রয়েছে, আসুন এটিকে বলি এবং আমরা বি টাইপের একটি ভেরিয়েবল রাখতে চাই যদি আমাদের কোনও বস্তু সত্যই হুডের নীচে একটি বি হয় তবে আমরা নিক্ষেপ করি। যদি এটি সত্যিকার অর্থে বি নয়, তবে আমাদের এটি রূপান্তর করতে হবে এবং প্রোগ্রামটি কীভাবে একটি এ থেকে বি পাওয়ার কথা রয়েছে তা নির্ধারণ করতে হবে def


এর মধ্যে একটি পোস্টে এরিক লিপার্ট উল্লেখ করেছিলেন যে ইমপ্লিট কাস্ট নামক কোনও জিনিস নেই এবং এটি অন্তর্নিহিত রূপান্তর । আমি পরস্পরের পরিবর্তে কাস্ট এবং রূপান্তর ব্যবহার করে আসছি। "অন্তর্নিহিত কাস্ট" বলতে কী ভুল? কোনও castালাইয়ের প্রয়োজন ছাড়াই যদি রূপান্তর অন্তর্নিহিত হয় না, তবে কেউ এটির "অন্তর্নিহিত castালাই" বলতে পারেন?
রাহুলগ_দেব

4
@ রাহুলআরওয়াল কাস্ট বলতে কী বোঝায় তা একটি অপারেশন যাতে আপনার স্পষ্টভাবে ইঙ্গিত করতে হবে যে প্রদত্ত প্রকারটি অন্য ধরণের বৈধ উদাহরণ (বা এটি তৈরি করা যেতে পারে)। যখন একটি অন্তর্নিহিত রূপান্তর বিদ্যমান থাকে, তখন প্রকারটিকে অন্য ধরণের হিসাবে গণ্য করার প্রয়োজন হয় না। সুতরাং "অন্তর্নিহিত castালাই" বলার অর্থ আসলেই আসে না (এরিকের মতো সম্ভাব্য কয়েকটি পরিস্থিতি বাদে যেখানে কোনও কাস্ট অপারেটর এটি বিকাশকারী টাইপ না করে যুক্ত করা হয় যেমন একটি ব্যবহার করার সময় foreach)। এই ব্যতিক্রমগুলির বাইরে কাস্টগুলি সংজ্ঞা অনুসারে সুস্পষ্ট ।
পরিবেশন করুন

6

থেকে MSDN:

সুস্পষ্ট রূপান্তর (ক্যাসেট): সুস্পষ্ট রূপান্তরগুলির জন্য একজন কাস্ট অপারেটর প্রয়োজন। রূপান্তরকরণে তথ্য হারিয়ে যেতে পারে বা যখন অন্য কারণে রূপান্তরটি সফল না হতে পারে তখন কাস্টিং প্রয়োজন । সাধারণ উদাহরণগুলির মধ্যে এমন ধরণের সংখ্যাসূচক রূপান্তর অন্তর্ভুক্ত থাকে যার স্বল্পতা বা কম পরিসীমা থাকে এবং একটি বেস-শ্রেণীর উদাহরণটি কোনও উত্পন্ন শ্রেণিতে রূপান্তর করা হয়।

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion

এবং আরো:

কাস্টার হ'ল সংকলককে স্পষ্টভাবে জানানোর একটি উপায় যা আপনি রূপান্তর করতে চান এবং আপনি জানেন যে ডেটা ক্ষতি হতে পারে।

আপনি System.Convertক্লাস ব্যবহার করতে পারবেন যখন আপনি অ-সামঞ্জস্যপূর্ণ প্রকারের মধ্যে রূপান্তর করতে চান । মূল পার্থক্য মধ্যে ভোটদান এবং ধর্মান্তরিত হয় কম্পাইল এবং রান টাইম । ধরণের রূপান্তর ব্যতিক্রমগুলি রান-টাইমে হাজির হয় , অর্থাত্ একটি টাইপ কাস্ট যা রান-টাইমে ব্যর্থ হয় InvalidCastExceptionতা নিক্ষেপের কারণ ঘটায় ।


উপসংহার: ing ালাইয়ের সময় আপনি সেই সংকলককে বলছেন aযা সত্যিই টাইপ করা হয় bএবং যদি প্রকল্পটি কোনও উদাহরণ ছাড়াই কোনও ত্রুটি ছাড়াই বিল্ড করে:

double s = 2;
int a = (int) s;

কিন্তু রূপান্তরটিতে আপনি সংকলকটিকে বলছেন যেখান থেকে একটি নতুন অবজেক্ট তৈরির উপায় রয়েছে a ধরণ b, দয়া করে এটা করতে এবং প্রকল্প কোনো ত্রুটি ছাড়া তৈরী করে কিন্তু আমি আগেই বলেছি যদি টাইপ কাস্ট রান সময়ে ব্যর্থ হলে, এটি একটি কারণ হবে InvalidCastExceptionথেকে নিক্ষেপ করা

উদাহরণস্বরূপ নীচের কোডটি কখনই সংকলিত হয় না কারণ সংকলক সনাক্ত করে যা প্রকারের অভিব্যক্তিটি কাস্ট করতে পারে না DateTime করতে টাইপেরint :

DateTime s = DateTime.Now;
int a = (int)(s);

তবে এটি সফলভাবে সংকলিত হয়েছে:

DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);

তবে রান-টাইমে আপনি পাবেন InvalidCastException যা বলে:

'ডেটটাইম' থেকে 'ইন্টার 32' এ অবৈধ কাস্ট।


4

আপনার উদাহরণে আপনি একটি ডাবল স্ট্রিং কাস্ট করার চেষ্টা করছেন (অবিচ্ছেদ্য টাইপ)।

এটি কাজ করার জন্য একটি সুস্পষ্ট রূপান্তর প্রয়োজন।

এবং আমার অবশ্যই উল্লেখ করতে হবে যে আপনি ডাবল মানের ভগ্নাংশের অংশটি যখন আপনি কোনও ইনট এ রূপান্তর করতে পারেন তার Convert.ToDoubleপরিবর্তে আপনি ব্যবহার করতে পারতেন Convert.ToInt64

যদি আপনার ভেরিয়েবলের মান "5.25" থাকে তবে ভ্যারডুবেলটি 5.00 হত (ইন্টার -64 এ রূপান্তর করার কারণে 0.25 এর ক্ষতি)

কাস্টিং বনাম রূপান্তর সম্পর্কে আপনার প্রশ্নের উত্তর দেওয়ার জন্য।

আপনার কাস্ট (সুস্পষ্ট কাস্ট) সুস্পষ্ট কাস্টের প্রয়োজনীয়তা পূরণ করে না। আপনি কাস্ট অপারেটরের সাথে কাস্ট করার চেষ্টা করছেন মানটি অবৈধ (অর্থাত্ অবিচ্ছেদ্য)।

MSালাই / রূপান্তরগুলির নিয়মের জন্য এই এমএসডিএন পৃষ্ঠাটি দেখুন


@ এডমাস্টারমাইন্ড 29 আমি আমার উত্তর আপডেট করেছি। আমি আশা করি এটি আপনার প্রশ্নের উত্তর দিয়েছে।
স্কার্টাগ

আমার প্রশ্নের সাথে সম্পর্কিত হিসাবে সুস্পষ্ট কাস্টের প্রয়োজনীয়তাগুলি কী? এটি "নন অবিচ্ছেদ্য" মানের ক্ষেত্রে?

@ এডমাস্টারমাইন্ড 29 হ্যাঁ আপনি যদি একটি সংখ্যার প্রকারে কাস্ট করার চেষ্টা করছেন মানটি যদি অ-সংখ্যাসূচক হয় তবে কাস্টটি অবৈধ .. একটি রূপান্তর প্রয়োজন ion
স্কার্টাগ

4

Convert.Doubleপদ্ধতি আসলে শুধু অভ্যন্তরীণভাবে আহ্বান Double.Parse(string)পদ্ধতি।

আমরাও Stringটাইপ নাDouble তাই ঢালাই সবসময় ব্যর্থ হবে ধরন, দুই ধরনের মধ্যে একটি সুনির্দিষ্ট / অন্তর্নিহিত রূপান্তর নির্ধারণ করুন।

দ্য Double.Parseপদ্ধতিতে প্রতিটি অক্ষর তাকান হবে stringএবং অক্ষরের মান উপর ভিত্তি করে একটি সাংখ্যিক মান গড়ে তুলতে string। অক্ষরের কোনওটি যদি অবৈধ হয় তবে Parseপদ্ধতিটি ব্যর্থ হয় ( Convert.Doubleপদ্ধতিটিও ব্যর্থ হয়)।


4
এবং এটি কীভাবে সুস্পষ্ট কাস্টের থেকে আলাদা?

4
একটি স্পষ্টরূপে castালাই ডেটা টাইপ কী তা দেখায় না, এটি কেবল বাইটগুলি দেখায়। উদাহরণস্বরূপ একটি পূর্ণসংখ্যার জন্য চর x = '1' ingালাই করা হবে, পূর্ণসংখ্যা 49 হবে কারণ সমাহারক '1' ascii টেবিলের # 49
ব্যবহারকারী 01751547

@ user1751547 সুতরাং, ব্যবহারকারী কি Convert.ToDouble()বাইটের বাইরে তাকান এবং ডেটা বিবেচনা করবেন?

@ ইউজার ১75৫১4747 that's I আমি মনে করি যে এই প্রশ্নের সঠিক উত্তর দেওয়ার জন্য এমন এক ধরনের অন্তর্দৃষ্টি প্রয়োজন। কেবল "এটি সংজ্ঞায়িত করা হয়নি" বলাটি সামান্য বিচূর্ণ।
পিপীলিকা পি

@ এডমাস্টারমাইন্ড 29 হ্যাঁ, এটি ইনপুট টাইপের দিকে নজর দেবে, এবং যদি এটি একটি স্ট্রিং হয় তবে এটি প্রতিটি চরিত্রের মধ্য দিয়ে যেত, জেনে রেখে যে যদি চরের আসকি মান 49 হয় তবে এটি '1' অক্ষর এবং এটি সঠিকভাবে রূপান্তর করে
user1751547

3

Ingালাইতে কোনও রূপান্তর জড়িত হয় না, অর্থাত্ কোনও মানের অভ্যন্তরীণ উপস্থাপনা পরিবর্তন হয় না। উদাহরণ:

object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.

আপনি এটি পছন্দ করতে একটি রূপান্তর doubleকরতে stringপারেন

double d = 5;
string s = d.ToString(); // -> "5"

// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"

আপনি একটি রূপান্তর করতে পারেন stringএকটি থেকে double(এখানে শুধু তাদের দুই) বিভিন্নভাবে:

string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number

বা নিরাপদ উপায়

string s = "5";
double d;
if (Double.TryParse(s, out d)) {
    Console.WriteLine("OK. Result = {0}", d);
} else {
    Console.WriteLine("oops!");
}

Convert.ToDouble()অভ্যন্তরীণ কলDouble.Parse() । এটা কি আমার পক্ষে Convert.ToDouble()বেশি ব্যবহার করা Double.Parse()বা না এবং কেন?

Convert.ToDoubleপ্রচুর ওভারলোড রয়েছে যা বিভিন্ন ধরণের ইনপুট গ্রহণ করে। কোনও স্ট্রিং পাস হয়ে গেলে ওভারলোড গ্রহণযোগ্য stringফেরত দেয় । এগুলি ছাড়াও আমি এটি ব্যবহারে কোনও অসুবিধে দেখতে পাচ্ছি না। 0.0null
অলিভিয়ার জ্যাকট-ডেসকোম্বেস

সুতরাং, হয় বা ... বা Double.Parse()আমার কাছে বিবেচনা করা উচিত এমন কিছু প্রস্তাব আছে?

Double.Parse()তুলনায় আরও সরাসরি Convert.ToDouble()। আপনি যদি নিশ্চিত হন যে আপনার স্ট্রিংটিতে একটি বৈধ সংখ্যা থাকবে তবে আপনি নিরাপদে এটি ব্যবহার করতে পারেন, অন্যথায় আমি আপনাকে ব্যবহার করার পরামর্শ দিচ্ছি Double.TryParse
অলিভিয়ার জ্যাকট-ডেসকোম্বেস

1
string variable = "5.00";     
double varDouble = (double)variable;

উপরের রূপান্তরটি কেবল ভাষা দ্বারা অনুমোদিত নয়। সংখ্যাসূচক প্রকারের জন্য সুস্পষ্ট কাস্টগুলির একটি তালিকা এখানে রয়েছে: http : //msdn.mic Microsoft.com/en-us/library/yht2cx7b.aspx আপনি দেখতে পাচ্ছেন, এমনকি প্রতিটি সংখ্যাসূচক প্রকারকে অন্য সংখ্যাসূচক ধরণের রূপান্তর করা যায়নি

কাস্টিং সম্পর্কে আরও কিছু তথ্য এখানে

এবং কীভাবে এটি রূপান্তর করতে পারে? টুডাবল ()?

আপনি যখন কোনও প্রকার কাস্ট করেন, তখন ডেটা কাঠামো পরিবর্তন হয় না। ভাল, সংখ্যার মান রূপান্তর ক্ষেত্রে আপনি কয়েকটি বিট শিথিল করতে পারেন বা অতিরিক্ত কিছু 0 বিট পেতে পারেন। তবে আপনি এখনও একটি সংখ্যা নিয়ে কাজ করছেন। আপনি কেবল এই সংখ্যাটি দ্বারা নেওয়া মেমরির পরিমাণ পরিবর্তন করছেন। সংকলক প্রয়োজনীয় সবকিছু করার জন্য এটি যথেষ্ট নিরাপদ।

তবে আপনি যখন কোনও সংখ্যায় স্ট্রিং কাস্ট করার চেষ্টা করছেন, আপনি এটি করতে পারবেন না কারণ ভেরিয়েবল দ্বারা নেওয়া মেমরির পরিমাণ পরিবর্তন করার পক্ষে এটি যথেষ্ট নয়। এই ক্ষেত্রে, 5.00স্ট্রিংটি "সংখ্যার" ক্রম হিসাবে: 53 (5) 46 (।) 48 (0) 48 (0) - এটি ASCII এর জন্য, তবে স্ট্রিংটিতে অনুরূপ কিছু থাকবে। যদি সংকলক কেবল স্ট্রিং থেকে প্রথম এন (4 টি ডাবল? নিশ্চিত নয়) বাইট নেয় - সেই টুকরোটিতে সম্পূর্ণ আলাদা ডাবল সংখ্যা থাকবে। একই সময়ে রূপান্তর করুন। টুডাবল () একটি বিশেষ অ্যালগরিদম চালান যা একটি স্ট্রিংয়ের প্রতিটি প্রতীক গ্রহণ করে, অঙ্কটি নির্ধারণ করে যা এটি উপস্থাপন করে এবং স্ট্রিং কোনও সংখ্যার প্রতিনিধিত্ব করে তবে আপনার জন্য একটি ডাবল সংখ্যা তৈরি করবে। পিএইচপি-র মতো ভাষাগুলি মোটামুটি ভাষায়, কনভার্টকে কল করবে T পটভূমিতে আপনার জন্য টুডাবল। তবে সি #, একটি স্ট্যাটিকালি টাইপ করা ভাষার মতো, এটি আপনার জন্য করবে না। এটি আপনাকে নিশ্চিত করতে দেয় যে কোনও ক্রিয়াকলাপ নিরাপদ এবং আপনি অপ্রত্যাশিতভাবে কিছু করার মতো কিছু পাবেন না:

double d = (double)"zzzz"

@ edmastermind29 আমার আপডেট হওয়া উত্তর দেখুন। আমি এটি ব্যাখ্যা করার চেষ্টা করেছি। ব্যাখ্যা নিখুঁত থেকে দূরে, তবে ধরুন এটি পার্থক্যটি ব্যাখ্যা করে।
ভিক্টর এস

1

এর মতো একটি ডাবলে স্ট্রিং কাস্ট করার অনুমতি নেই # যার কারণে আপনি একটি ব্যতিক্রম পান, আপনার স্ট্রিং রূপান্তরিত হওয়া দরকার ( এমএসডিএন ডক যা গ্রহণযোগ্য রূপান্তর পথ দেখায়)। এটি কেবল কারণ একটি স্ট্রিংয়ে অংকিত অংকিত ডেটা থাকে না, তবে বিভিন্ন সংখ্যার ধরণগুলি (নাল মান ব্যতীত) করবে। কConvert এমন একটি পদ্ধতি চালাবে যা এটির একটি সংখ্যার মান হিসাবে রূপান্তরিত করা যায় কিনা তা দেখতে স্ট্রিংটি পরীক্ষা করবে। যদি এটি করতে পারে, তবে এটি সেই মানটি ফিরিয়ে দেবে। যদি এটি না পারে তবে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলবে।

এটিকে রূপান্তর করতে আপনার কাছে বেশ কয়েকটি বিকল্প রয়েছে। আপনি Convertআপনার প্রশ্নে সেই পদ্ধতিটি ব্যবহার করেছেন Parseযা এখানে বেশিরভাগ ক্ষেত্রে সাদৃশ্যপূর্ণ Convertতবে ট্রাইপার্সেও আপনার নজর দেওয়া উচিত যা আপনাকে এটি করতে দেয়:

string variable = "5.00"; 

double varDouble;

if (Double.TryParse(variable, out varDouble)) {
    //Code that runs if the conversion succeeded.
} else {
    //Code that runs if the conversion failed.
}

আপনি Convertবা Parseএকটি অ-সংখ্যাগত স্ট্রিংয়ের চেষ্টা করা উচিত এটি সম্ভাব্য ব্যতিক্রম এড়ায়।


এটা আমার সুবিধা ব্যবহার করতে হয় TryParseবেশি Convertকারণ TryParseচেক যদি রূপান্তর সফল?

@ এডমাস্টারমাইন্ড 29 রূপান্তর ব্যর্থ হলে রূপান্তর একটি ব্যতিক্রম ছুঁড়ে ফেলবে। ট্রাইপর্স একটি বুলিয়ান ফিরিয়ে দেবে, সত্য যদি রূপান্তরটি সফল হয় এবং যদি এটি ব্যর্থ হয় তবে মিথ্যা।
কেইন

1

double varDouble = (double)variablevariableইতিমধ্যে একটি ডাবল অনুমান । যদি variableডাবল না হয় (এটি একটি স্ট্রিং) তবে এটি ব্যর্থ হবে। double varDouble = Convert.ToDouble(variable)এটি বলে - যেমন রূপান্তরিত করে। এটি পার্স করতে পারলে বা অন্যথায় একটি ডাবল বের করতে পারেvariable তবে তা হবে will

আমি দ্বিতীয়টি ব্যবহার করছি Double.Parseবা Double.TryParseকারণ এটি আরও স্পষ্টভাবে ইঙ্গিত করে যা ঘটছে বলে মনে করা হচ্ছে। আপনি একটি স্ট্রিং দিয়ে শুরু করছেন এবং এটি একটি দ্বিগুণ রূপান্তরিত হবে বলে আশা করছেন। যদি কোনও সন্দেহ থাকে তবে ব্যবহার করুন TryParse

যদি variableকোনও পদ্ধতির যুক্তি হয় তবে টাইপটিকে ডাবল করুন change সঠিক ধরণের সরবরাহের জন্য কলারকে দায়বদ্ধ করুন। এইভাবে সংকলকটি আপনার জন্য কাজ করে।


-1

সর্বাধিক গুরুত্বপূর্ণ পার্থক্যটি হ'ল যদি টাইপ কাস্টিং ব্যবহার করা হয় এবং রূপান্তর ব্যর্থ হয় (বলুন যে আমরা একটি খুব বড় ভাসমান মানকে ইনট হিসাবে রূপান্তর করছি) কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হবে না এবং কোনও অন্তর্নির্মিত ন্যূনতম মান প্রদর্শিত হবে। তবে কনভার্ট ব্যবহারের ক্ষেত্রে, এই জাতীয় দৃশ্যের জন্য একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.