যেহেতু true
স্ট্রিং টাইপ নয় তাই null + true
স্ট্রিং কেমন?
string s = true; //Cannot implicitly convert type 'bool' to 'string'
bool b = null + true; //Cannot implicitly convert type 'string' to 'bool'
এর পিছনে কারণ কী?
যেহেতু true
স্ট্রিং টাইপ নয় তাই null + true
স্ট্রিং কেমন?
string s = true; //Cannot implicitly convert type 'bool' to 'string'
bool b = null + true; //Cannot implicitly convert type 'string' to 'bool'
এর পিছনে কারণ কী?
উত্তর:
উদ্ভট হিসাবে মনে হতে পারে, এটি কেবল সি # ভাষার বৈশিষ্ট থেকে প্রাপ্ত বিধিগুলি অনুসরণ করছে।
বিভাগ থেকে 7.3.4:
এক্স অপ y ফর্মটির একটি অপারেশন, যেখানে ওপ একটি ওভারলোডযোগ্য বাইনারি অপারেটর, এক্স প্রকার এক্স টাইপের এক্সপ্রেশন এবং y প্রকার Y এর বহিঃপ্রকাশ যা নিম্নরূপে প্রক্রিয়া করা হয়:
- অপারেশন অপারেটর অপের জন্য এক্স এবং ওয়াই দ্বারা সরবরাহ করা প্রার্থী ব্যবহারকারী-সংজ্ঞায়িত অপারেটরগুলির সেট (x, y) নির্ধারিত হয়। এই সেটটিতে এক্স দ্বারা সরবরাহ করা প্রার্থী অপারেটর এবং ওয়াই দ্বারা সরবরাহিত প্রার্থী অপারেটরগুলির ইউনিয়ন, প্রতিটি §7.3.5 এর নিয়ম ব্যবহার করে নির্ধারিত থাকে। যদি এক্স এবং ওয়াই একই ধরণের হয়, বা যদি এক্স এবং ওয়াই কোনও সাধারণ বেস প্রকার থেকে উদ্ভূত হয়, তবে ভাগ করা প্রার্থী অপারেটরগুলি কেবল একবারে সম্মিলিত সেটে উপস্থিত হয়।
- যদি প্রার্থী ব্যবহারকারী-সংজ্ঞায়িত অপারেটরগুলির সেটটি খালি না থাকে, তবে এটি অপারেশনের জন্য প্রার্থী অপারেটরদের সেট হয়ে যায়। অন্যথায়, পূর্বনির্ধারিত বাইনারি অপারেটর বিকল্প প্রয়োগগুলি, তাদের উত্তোলিত ফর্মগুলি সহ, অপারেশনের জন্য প্রার্থী অপারেটরগুলির সেট হয়ে যায়। প্রদত্ত অপারেটরের পূর্বনির্ধারিত বাস্তবায়ন অপারেটরের বর্ণনায় নির্দিষ্ট করা হয় (.87.8 থেকে §7.12)।
- আর্গুমেন্ট লিস্টের (x, y) সম্মানের সাথে সেরা অপারেটর নির্বাচন করতে প্রার্থী অপারেটরদের সেটগুলিতে .57.5.3 এর ওভারলোড রেজোলিউশন নিয়মগুলি প্রয়োগ করা হয় এবং এই অপারেটর ওভারলোড রেজোলিউশন প্রক্রিয়ার ফলাফল হয়ে ওঠে। যদি ওভারলোড রেজোলিউশন কোনও একক সেরা অপারেটর নির্বাচন করতে ব্যর্থ হয় তবে একটি বাধ্যতামূলক-সময় ত্রুটি ঘটে।
সুতরাং, আসুন ঘুরে এই মাধ্যমে চলুন।
এক্সটি এখানে নাল টাইপ - বা কোনও ধরণের নয়, আপনি যদি সেভাবে এটি ভাবতে চান তবে। এটি কোনও প্রার্থী সরবরাহ করছে না। Y হ'ল এটি bool
কোনও ব্যবহারকারী-সংজ্ঞায়িত +
অপারেটর সরবরাহ করে না। সুতরাং প্রথম পদক্ষেপটি কোনও ব্যবহারকারী-সংজ্ঞায়িত অপারেটরদের খুঁজে পায় না।
সংকলকটি পূর্বনির্ধারিত বাইনারি অপারেটর + বাস্তবায়ন এবং তাদের উত্তোলিত ফর্মগুলির সন্ধান করে দ্বিতীয় বুলেট পয়েন্টে চলে যায়। এগুলি অনুমানের 7.8.4 বিভাগে তালিকাভুক্ত করছে।
যদি আপনি সেই পূর্বনির্ধারিত অপারেটরগুলির মধ্যে নজর দেন তবে কেবলমাত্র যা প্রযোজ্য তা হ'ল string operator +(string x, object y)
। সুতরাং প্রার্থী সেট একটি একক প্রবেশ আছে। এটি চূড়ান্ত বুলেট পয়েন্টকে খুব সহজ করে তোলে ... ওভারলোড রেজোলিউশন সেই অপারেটরটিকে বাছাই করে, এর সামগ্রিক প্রকাশের ধরণ দেয় string
।
একটি আকর্ষণীয় বিষয় হ'ল অনির্ধারিত প্রকারের অন্যান্য ব্যবহারকারী-সংজ্ঞায়িত অপারেটর উপস্থিত থাকলেও এটি ঘটবে। উদাহরণ স্বরূপ:
// Foo defined Foo operator+(Foo foo, bool b)
Foo f = null;
Foo g = f + true;
এটি ঠিক আছে, তবে এটি নাল আক্ষরিক জন্য ব্যবহৃত হয় না, কারণ সংকলকটি সন্ধান করতে জানে না Foo
। এটি কেবল বিবেচনা করতেই জানে string
কারণ এটি একটি পূর্বনির্ধারিত অপারেটর স্পষ্টতই তালিকাটিতে তালিকাভুক্ত। (আসলে, এটি স্ট্রিং ধরণের দ্বারা সংজ্ঞায়িত অপারেটর নয় ... 1 ) এর অর্থ এই সংকলন করতে ব্যর্থ হবে:
// Error: Cannot implicitly convert type 'string' to 'Foo'
Foo f = null + true;
অন্যান্য দ্বিতীয় অপারেন্ড প্রকারগুলি অবশ্যই অন্য কিছু অপারেটর ব্যবহার করবে:
var x = null + 0; // x is Nullable<int>
var y = null + 0L; // y is Nullable<long>
var z = null + DayOfWeek.Sunday; // z is Nullable<DayOfWeek>
1 আপনি ভাবতে পারেন কেন স্ট্রিং + অপারেটর নেই। এটি একটি যুক্তিসঙ্গত প্রশ্ন এবং আমি কেবল উত্তরটি অনুমান করছি তবে এই অভিব্যক্তিটি বিবেচনা করুন:
string x = a + b + c + d;
তাহলে string
C # এর কম্পাইলার কোন বিশেষ-বা ছোট হাতের অক্ষর ছিল, এই কার্যকরভাবে যেমন শেষ হবে:
string tmp0 = (a + b);
string tmp1 = tmp0 + c;
string x = tmp1 + d;
সুতরাং এটি দুটি অপ্রয়োজনীয় মধ্যবর্তী স্ট্রিং তৈরি করেছে। যাইহোক, সংকলকটির মধ্যে বিশেষ সমর্থন রয়েছে বলে, এটি প্রকৃতপক্ষে উপরেরটি সংকলন করতে সক্ষম:
string x = string.Concat(a, b, c, d);
যা ঠিক একবারে সমস্ত ডেটা অনুলিপি করে ঠিক সঠিক দৈর্ঘ্যের একক স্ট্রিং তৈরি করতে পারে। খুশী হলাম।
true
রূপান্তরিত না হওয়া থেকে ত্রুটি আসে string
। অভিব্যক্তিটি বৈধ হলে টাইপটি হবে string
তবে এই ক্ষেত্রে স্ট্রিংয়ে রূপান্তর করতে ব্যর্থতা পুরো ভাবটিকে ত্রুটি করে তোলে এবং তাই কোনও প্রকার নেই has
x
টাইপ হয় string
। নোট করুন যে এখানে স্বাক্ষর ব্যবহৃত হয়েছে string operator+(string, object)
- এটি রূপান্তর bool
করে object
(যা ভাল) তেমন নয় string
।
এর কারণ হ'ল একবার আপনি তত্ক্ষণাত +
সি # অপারেটর বাইন্ডিং বিধি চালু করে । এটি +
উপলব্ধ অপারেটরদের সেট বিবেচনা করবে এবং সেরা ওভারলোড নির্বাচন করবে। এই অপারেটরগুলির মধ্যে একটি নিম্নরূপ
string operator +(string x, object y)
এই ওভারলোডটি এক্সপ্রেশনটিতে যুক্তির ধরণের সাথে সামঞ্জস্যপূর্ণ null + true
। সুতরাং এটি অপারেটর হিসাবে নির্বাচিত হয় এবং মূলত ((string)null) + true
যা মূল্যকে মূল্যায়ন করে তা হিসাবে মূল্যায়ন করা হয় "True"
।
সি # ভাষা অনুচ্ছেদের 7..7.৪ বিভাগে এই রেজোলিউশনের চারপাশের বিশদ রয়েছে।
operator+
জন্য string
। পরিবর্তে এটি কেবল সংকলকের মনে বিদ্যমান এবং এটি কেবল এটিকে কলগুলির জন্য অনুবাদ করেstring.Concat
সংকলকটি অপারেটর + () এর শিকারে বেরিয়ে যায় যা প্রথমে নাল যুক্তি নিতে পারে। মানক মানের ধরণের কোনওটিই যোগ্যতা অর্জন করে না, নাল তাদের জন্য একটি কার্যকর মান নয়। এক এবং একমাত্র ম্যাচটি হ'ল System.String.operator + (), কোনও অস্পষ্টতা নেই।
অপারেটরের 2 য় আর্গুমেন্টও একটি স্ট্রিং। এটি কাপুয়ে যায়, স্পষ্টভাবে মুলকে স্ট্রিংয়ে রূপান্তর করতে পারে না।
আকর্ষণীয়ভাবে, রিফ্লেক্টর ব্যবহার করে নিচের কোডটি কী উত্পন্ন হয় তা পরিদর্শন করতে:
string b = null + true;
Console.WriteLine(b);
সংকলক দ্বারা এটিতে রূপান্তরিত হয়:
Console.WriteLine(true);
এই "অপ্টিমাইজেশান" এর পিছনে যুক্তিটি আমি কিছুটা অদ্ভুত বলেছি অবশ্যই, এবং অপারেটর নির্বাচনের সাথে আমি প্রত্যাশা করব ছড়াটি করি না।
এছাড়াও, নিম্নলিখিত কোড:
var b = null + true;
var sb = new StringBuilder(b);
রূপান্তরিত হয়
string b = true;
StringBuilder sb = new StringBuilder(b);
string b = true;
সংকলক যেখানে প্রকৃতপক্ষে গৃহীত হয় না।
null
নাল স্ট্রিংয়ে ফেলে দেওয়া হবে, এবং সেখানে বুল থেকে স্ট্রিংয়ে অন্তর্নিহিত রূপান্তরকারী রয়েছে তাই স্ট্রিংতে true
কাস্ট করা হবে এবং তারপরে, +
অপারেটর প্রয়োগ করা হবে: এটি এর মতো: স্ট্রিং স্ট্র = "" + ট্রুস্ট্রিং ();
আপনি যদি এটি ইল্ডাসমের সাথে পরীক্ষা করেন:
string str = null + true;
এটি হিসাবে নমো:
.locals init ([0] string str)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: box [mscorlib]System.Boolean
IL_0007: call string [mscorlib]System.String::Concat(object)
IL_000c: stloc.0
var b = (null + DateTime.Now); // String
var b = (null + 1); // System.Nullable<Int32> | same with System.Single, System.Double, System.Decimal, System.TimeSpan etc
var b = (null + new Object()); // String | same with any ref type
ক্রেজি ?? না, এর পিছনে অবশ্যই কোনও কারণ থাকতে হবে।
কেউ ফোন Eric Lippert
...
এর কারণটি সুবিধার্থে (সংলগ্ন স্ট্রিংগুলি একটি সাধারণ কাজ)।
যেমন বোল্টক্লক বলেছেন, '+' অপারেটর সংখ্যার প্রকার, স্ট্রিংগুলিতে সংজ্ঞায়িত এবং আমাদের নিজস্ব ধরণের জন্যও (অপারেটর ওভারলোডিং) সংজ্ঞায়িত করা যায়।
যদি আর্গুমেন্টের ধরণগুলিতে ওভারলোডেড '+' অপারেটর না থাকে এবং তারা সংখ্যার ধরণের না হয় তবে সংকলকটি স্ট্রিং কনকেন্টেশনে ডিফল্ট।
সংকলক String.Concat(...)
যখন আপনি '+' ব্যবহার করে সম্মতি জানাতে কল সন্নিবেশ করান এবং কনক্যাট প্রয়োগের মাধ্যমে প্রতিটি বস্তুতে টসস্ট্রিং কল আসে calls