নুল স্ট্রিংগুলিকে কেন লড়াই করা বৈধ তবে “নাল.টোস্ট্রিং ()” কল করা যায় না কেন?


126

এটি বৈধ সি # কোড

var bob = "abc" + null + null + null + "123";  // abc123

এটি বৈধ সি # কোড নয়

var wtf = null.ToString(); // compiler error

প্রথম বিবৃতিটি বৈধ কেন?


97
আপনার null.ToString()নামটি দেওয়া হয়েছে এটি আমি অদ্ভুত বলে মনে করি wtf। কেন আপনাকে অবাক করে? আপনি যখন প্রথম স্থান থেকে কল করার কিছু নেই তখন আপনি কোনও ইনস্ট্যান্স পদ্ধতিতে কল করতে পারবেন না।
BoltClock

11
@ বোল্টক্লক: অবশ্যই কোনও নাল উদাহরণে একটি উদাহরণ পদ্ধতি কল করা সম্ভব। সি # তে কেবল সম্ভব নয়, তবে সিএলআর তে খুব বৈধ :)
লিপি

1
স্ট্রিং.কনক্যাট সম্পর্কিত উত্তরগুলি প্রায় সঠিক। প্রকৃতপক্ষে, প্রশ্নের নির্দিষ্ট উদাহরণটি ধ্রুবক ভাঁজগুলির একটি , এবং প্রথম পংক্তির নালগুলি সংকলক দ্বারা মুছে ফেলা হয় - অর্থাৎ তারা আর নেই বলে রানটাইমে কখনই মূল্যায়ন করা হয় না-সংকলক সেগুলি মুছে ফেলেছে। আমি আরও তথ্যের জন্য এখানে স্ট্রিংসকে একত্রীকরণ এবং ধ্রুবক ভাঁজ করার জন্য সমস্ত বিধিবিধানের জন্য একটি সামান্য একাকীকরণ লিখেছি: স্ট্যাকওভারফ্লো / প্রশ্ন / 9132338/…
ক্রিস শাইন

77
আপনি কোনও স্ট্রিংয়ে কিছু যোগ করতে পারবেন না তবে আপনি কিছুতেই স্ট্রিং তৈরি করতে পারবেন না।
আরজিবি

দ্বিতীয় বিবৃতি বৈধ নয়? class null_extension { String ToString( Object this arg ) { return ToString(arg); } }
ctrl-alt-delor

উত্তর:


163

প্রথম এক কাজ করার কারণ:

এমএসডিএন থেকে :

স্ট্রিং কনটেনটেশন অপারেশনগুলিতে, সি # সংকলক একটি নাল স্ট্রিংকে খালি স্ট্রিংয়ের মতোই আচরণ করে তবে এটি মূল নাল স্ট্রিংয়ের মান রূপান্তর করে না।

বাইনারি অপারেটর সম্পর্কিত আরও তথ্য :

বাইনারি + অপারেটর স্ট্রিং সংমিশ্রণ সম্পাদন করে যখন এক বা উভয় অপারেন্ড টাইপ স্ট্রিংয়ের হয়।

স্ট্রিং কনটেনটেশনের একটি অপারেন্ড যদি নাল হয় তবে একটি খালি স্ট্রিং প্রতিস্থাপন করা হয়। অন্যথায়, কোনও অ-স্ট্রিং আর্গুমেন্ট ToStringটাইপ অবজেক্ট থেকে উত্তরাধিকার সূত্রে প্রাপ্ত ভার্চুয়াল পদ্ধতিতে অনুরোধ করে তার স্ট্রিং উপস্থাপনায় রূপান্তরিত হয় ।

যদি ToStringফিরে আসে null, একটি খালি স্ট্রিং প্রতিস্থাপন করা হয়।

দ্বিতীয়টিতে ত্রুটির কারণ হ'ল:

নাল (সি # রেফারেন্স) - নাল কীওয়ার্ডটি একটি আক্ষরিক যা একটি নাল রেফারেন্স উপস্থাপন করে, যা কোনও বস্তুর উল্লেখ করে না। নাল হল রেফারেন্স-টাইপ ভেরিয়েবলের ডিফল্ট মান।


1
তাহলে কি এই কাজ করবে? var wtf = ((String)null).ToString();আমি সম্প্রতি জাভাতে কাজ করছি যেখানে নাল এর ingালাই সম্ভব, আমি সি # এর সাথে কাজ করার কিছুক্ষণ হয়েছে।
জোহেম 30'12

14
@ জোহেম: আপনি এখনও নাল বস্তুর উপর কোনও পদ্ধতি কল করার চেষ্টা করছেন, তাই আমি অনুমান করছি না। এটি null.ToString()বনাম হিসাবে মনে করুন ToString(null)
Svish

@ এসভিশ হ্যাঁ, এখন আমি এটি আবারও ভাবি, এটি একটি নাল বস্তু, সুতরাং আপনি ঠিক বলেছেন, এটি কাজ করবে না। এটি জাভাতেও নয়: নাল পয়েন্টার ব্যতিক্রম। কিছু মনে করো না. আপনার উত্তর জন্য Tnx! [সম্পাদনা: এটি জাভাতে পরীক্ষা করা হয়েছে: নালপয়েন্টারএক্সসেপশন। Castালাইয়ের সাথে পার্থক্যটি যা এটি সংকলন করে, castালাই ছাড়াই তা হয় না]।
জোহেম 30'12

সাধারণত নাল কীওয়ার্ডটি ইচ্ছাকৃতভাবে একত্রীকরণ বা টোস্ট্রিংয়ের কোনও কারণ নেই। আপনার যদি খালি স্ট্রিংয়ের প্রয়োজন হয় তবে স্ট্রিংটি ব্যবহার করুন mp যদি আপনার যদি স্ট্রিং ভেরিয়েবলটি নাল হয় তা যাচাই করতে হয় তবে আপনি (মাইস্ট্রিং == নাল) অথবা স্ট্রিং ব্যবহার করতে পারেন sসনলআরআম্পিটি (মাইস্ট্রিং)। বিকল্প হিসাবে নাল স্ট্রিং ভেরিয়েবলটিকে স্ট্রিংয়ে রূপান্তর করতে Eএমন ব্যবহার করুন MyNewString = (মাইস্ট্রিং == নল ?? স্ট্রিং Eম্পটি)
সিউউ

@ জোহেম এটি ingালাই এটি সংকলন করে তুলবে তবে এটি রানটাইমে একটি নুলারফেরান এক্সেক্সশনটি নিক্ষেপ করবে
জিরোহেন

108

কারণ +সি # তে অপারেটর অভ্যন্তরীণভাবে অনুবাদ করে String.Concatযা একটি স্থির পদ্ধতি। এবং এই পদ্ধতিটি nullখালি স্ট্রিংয়ের মতো আচরণ করে । আপনি যদি String.Concatপ্রতিফলকের উত্সটির দিকে তাকান, আপনি এটি দেখতে পাবেন:

// while looping through the parameters
strArray[i] = (str == null) ? Empty : str;
// then concatenate that string array

(এমএসডিএন এটিরও উল্লেখ করেছে: http://msdn.microsoft.com/en-us/library/k9c94ey1.aspx )

অন্যদিকে, ToString()এটি একটি উদাহরণ পদ্ধতি যা আপনি কল করতে পারবেন না null(কোন ধরণের জন্য ব্যবহার করা উচিত null?)।


2
স্ট্রিং ক্লাসে যদিও কোনও + অপারেটর নেই .. সুতরাং এটি কি সংকলকটি স্ট্রিং.কনকটে অনুবাদ করে?
সুপারলজিকাল

@ সুপারলজিকাল হ্যাঁ, সংকলক এটি করে। সুতরাং আসলে, +সি # তে স্ট্রিংগুলিতে অপারেটর কেবল সিনট্যাকটিক চিনির জন্য String.Concat
Botz3000

এতে যুক্ত হচ্ছে: সংকলক স্বয়ংক্রিয়ভাবে কনকটের ওভারলোডটিকে সবচেয়ে বেশি অর্থ দেয়। উপলব্ধ ওভারলোডগুলি হ'ল 1, 2 বা 3 অবজেক্ট পরামিতি, 4 অবজেক্ট প্যারামিটার + __arglistএবং একটি paramsঅবজেক্ট অ্যারের সংস্করণ।
ওয়ারম্বো

সেখানে কোন স্ট্রিং অ্যারে সংশোধন করা হচ্ছে? না Concatসবসময় অ নাল স্ট্রিং একটি নতুন অ্যারে এমনকি যখন অ নাল স্ট্রিং একটি অ্যারে দেওয়া, নাকি অন্য কিছু ঘটছে সৃষ্টি করেছেন?
সুপারক্যাট

@ সুপের্যাট সংশোধিত অ্যারেটি একটি নতুন অ্যারে, যা পরে একটি ব্যক্তিগত সহায়ক পদ্ধতিতে দেওয়া হয়। আপনি নিজেই প্রতিচ্ছবি ব্যবহার করে কোডটি দেখতে পারেন।
Botz3000

29

প্রথম নমুনা অনুদিত হবে:

var bob = String.Concat("abc123", null, null, null, "abs123");

দ্য Concatপদ্ধতি চেক ইনপুট এবং একটি খালি স্ট্রিং হিসেবে নাল অনুবাদ

দ্বিতীয় নমুনা অনুদিত হবে:

var wtf = ((object)null).ToString();

সুতরাং এখানে একটি nullরেফারেন্স ব্যতিক্রম উত্পন্ন হবে


আসলে, একটি AccessViolationExceptionনিক্ষেপ করা হবে :)
লেপি

আমি সবেমাত্র :) ((object)null).ToString()=> AccessViolation ((object)1 as string).ToString()=> করেছিNullReference
লিপি

1
আমি নুলারফেরান এক্সেপশন পেয়েছি। ডিএন 4.0
ভাইচাসলভ স্মৃতিখ

মজাদার. আমি যখন ((object)null).ToString()একটি ভিতরে try/catchরাখি আমিও পেতে পারি NullReferenceException
লেপি

3
@ ইপ্পি এটি বাদ দিয়ে অ্যাক্সেসভায়োলশনকে ফেলে দেয় না (কেন হবে?) - নুলরফেরেন্সএক্সেপশন এখানে।
jeroenh

11

আপনার কোডের প্রথম অংশটি ঠিক এর মতোই আচরণ করা হবে String.Concat,

আপনি যখন স্ট্রিং যুক্ত করেন তখন সি # সংকলকটি কী বলে। " abc" + nullঅনুবাদ করা হয় String.Concat("abc", null),

এবং অভ্যন্তরীণভাবে, সেই পদ্ধতিটি প্রতিস্থাপন nullকরে String.Empty। সুতরাং, এজন্য আপনার কোডের প্রথম অংশটি কোনও ব্যতিক্রম ছুঁড়ে না। এটা ঠিক মত

var bob = "abc" + string.Empty + string.Empty + string.Empty + "123";  //abc123

এবং আপনার কোডের ২ য় অংশে ব্যতিক্রম ছুঁড়েছে কারণ 'নাল' কোনও বস্তু নয়, নাল কীওয়ার্ডটি একটি আক্ষরিক যা নাল রেফারেন্সকে উপস্থাপন করে যা কোনও বস্তুর উল্লেখ করে না। নাল হল রেফারেন্স-টাইপ ভেরিয়েবলের ডিফল্ট মান।

এবং ' ToString()' হ'ল এমন একটি পদ্ধতি যা কোনও বস্তুর উদাহরণ দিয়ে ডাকা যেতে পারে তবে কোনও আক্ষরিক নয়।


3
String.Emptyসমান নয় null। এটি যেমন কিছু পদ্ধতিতে ঠিক একইভাবে চিকিত্সা করা হয় String.Concat। উদাহরণস্বরূপ, যদি আপনার কাছে স্ট্রিং ভেরিয়েবল সেট থাকে null, String.Emptyআপনি যদি কোনও পদ্ধতিতে কল করার চেষ্টা করেন তবে সি # এটির সাথে প্রতিস্থাপন করবে না ।
Botz3000

3
প্রায়। সি # এর nullমতো চিকিত্সা করা হয় না String.Empty, এটি ঠিক এর মতোই ব্যবহার করা হয় String.Concat, আপনি যখন স্ট্রিং যুক্ত করেন তখন সি # সংকলক বলে। অভ্যন্তরীণভাবে "abc" + nullঅনুবাদ করা হয় String.Concat("abc", null), এবং অভ্যন্তরীণভাবে, সেই পদ্ধতিটি পরিবর্তিত nullহয় String.Empty। দ্বিতীয় অংশটি সম্পূর্ণ সঠিক।
বটজ 3000

9

। নেট এর আগে সিওএম কাঠামোয়, কোনও রুটিনের জন্য এটি প্রয়োজনীয় ছিল যখন এটি সম্পন্ন করার পরে এটি মুক্ত করার জন্য একটি স্ট্রিং পেয়েছিল। যেহেতু খালি স্ট্রিংগুলি রুটিনগুলিতে প্রবেশ করা এবং বাইরে যাওয়া খুব সাধারণ ছিল এবং একটি নাল পয়েন্টারকে "ফ্রি" করার চেষ্টা করার কারণে বৈধ ডো-না-অপারেশন হিসাবে সংজ্ঞায়িত করা হয়েছিল, তাই মাইক্রোসফ্ট একটি নাল স্ট্রিং পয়েন্টারটি একটি ফাঁকা স্ট্রিং প্রতিনিধিত্ব করার সিদ্ধান্ত নিয়েছে।

সিওএমের সাথে কিছু সামঞ্জস্যের অনুমতি দেওয়ার জন্য। নেট এ অনেক রুটিন একটি শূন্য স্ট্রিং হিসাবে একটি নাল বস্তুকে আইনী উপস্থাপন হিসাবে ব্যাখ্যা করবে। বেশ কয়েকটি সামান্য পরিবর্তন। নেট এবং এর ভাষাগুলির সাথে (বিশেষত উদাহরণস্বরূপ সদস্যদের "ভার্চুয়াল হিসাবে প্রার্থনা করবেন না" চিহ্নিত করার অনুমতি দেওয়া), মাইক্রোসফ্ট nullঘোষিত টাইপের স্ট্রিংয়ের অবজেক্টগুলিকে ফাঁকা স্ট্রিংয়ের মতো আরও বেশি আচরণ করতে পারে। মাইক্রোসফ্ট যদি এটি করে থাকে, তবে এটি Nullable<T>কিছুটা আলাদাভাবে কাজও করতে হত (যাতে Nullable<String>তারা আইএমএইচও-তে যেভাবেই করা উচিত ছিল) এবং / অথবা এমন একটি NullableStringধরণ সংজ্ঞায়িত করতে পারে যা বেশিরভাগের সাথে আদান-প্রদানযোগ্য হতে পারে তবে কোন বিষয়টিকে Stringবিবেচনা করবে না nullএকটি বৈধ খালি স্ট্রিং হিসাবে।

যেমনটি রয়েছে, কিছু প্রসঙ্গ রয়েছে যার মধ্যে একটিকে nullবৈধ খালি স্ট্রিং হিসাবে বিবেচনা করা হবে এবং অন্যগুলি এটিতে হবে না। ভয়াবহ সহায়ক পরিস্থিতি নয়, তবে কোনটি প্রোগ্রামারদের সচেতন হওয়া উচিত। সাধারণভাবে, ফর্মটির এক্সপ্রেশনগুলি stringValue.someMemberযদি ব্যর্থ stringValueহয় nullতবে বেশিরভাগ ফ্রেমওয়ার্ক পদ্ধতি এবং অপারেটরগুলি প্যারামিটার nullহিসাবে স্ট্রিংকে খালি স্ট্রিং হিসাবে বিবেচনা করবে ।


5

'+'একটি ইনফিক্স অপারেটর। যে কোনও অপারেটরের মতো এটি সত্যই কোনও পদ্ধতি কল করছে। আপনি একটি অন-ইনফিক্স সংস্করণটি কল্পনা করতে পারেন"wow".Plus(null) == "wow"

প্রয়োগকারী এই জাতীয় কিছু নিয়ে সিদ্ধান্ত নিয়েছে ...

class String
{
  ...
  String Plus(ending)
  {
     if(ending == null) return this;
     ...
  }
} 

সুতরাং .. আপনার উদাহরণ হয়ে যায়

var bob = "abc".Plus(null).Plus(null).Plus(null).Plus("123");  // abc123

যা হিসাবে একই

var bob = "abc".Plus("123");  // abc123

কোনও বিন্দুতে নাল একটি স্ট্রিং হয়ে যায় না। তাই null.ToString()ভিন্ন যে null.VoteMyAnswer()। ;)


সত্যিই, এটি আরও পছন্দ var bob = Plus(Plus(Plus(Plus("abc",null),null),null),"123");। অপারেটর ওভারলোডগুলি তাদের হৃদয়ে স্থিতিশীল পদ্ধতি: এমএসডিএন.মাইক্রোসফট.ইন / লিবেরি / এস 53ehcz3 ( v=VS.71 ) .aspx তারা না থাকলে var bob = null + "abc";বা বিশেষত string bob = null + null;বৈধ হবে না।
বেন মোশার

আপনি ঠিক বলেছেন, আমি কেবল অনুভব করেছি যে আমি যদি সেভাবে এটি ব্যাখ্যা করি তবে আমি খুব বিভ্রান্ত হব।
নাইজেল থর্ন

3

আমি অনুমান করি কারণ এটি আক্ষরিক যা কোনও বস্তুর উল্লেখ করে না। ToString()একটি প্রয়োজন object


3

কেউ এই আলোচনার থ্রেডে বলেছিলেন যে আপনি কিছুতেই স্ট্রিং তৈরি করতে পারবেন না। (যা আমার মনে হয় একটি দুর্দান্ত বাক্যাংশ)। তবে হ্যাঁ - আপনি করতে পারেন :-), যেমন নিম্নলিখিত উদাহরণটি দেখায়:

var x = null + (string)null;     
var wtf = x.ToString();

সূক্ষ্ম কাজ করে এবং একটি ব্যতিক্রম মোটেও ছুঁড়ে না। পার্থক্যটি হ'ল আপনাকে একটি নালকে একটি স্ট্রিংয়ে ফেলে দিতে হবে - আপনি যদি (স্ট্রিং) কাস্টটি সরিয়ে ফেলেন তবে উদাহরণটি এখনও কম্পাইল করে তবে রান-টাইম ব্যতিক্রম ছুঁড়ে ফেলে: "অপারেটর '+' অপারেশনগুলিতে অস্পষ্ট '<null>' এবং '<null>' টাইপ করুন।

এনবি উপরের কোড উদাহরণে, x এর মান শূন্য নয় যেমনটি আপনি প্রত্যাশা করতে পারেন, এটি আসলে একটি খালি স্ট্রিং যখন আপনি একটি স্ট্রিংয়ের মধ্যে অপারেন্ডকে কাস্ট করেছেন।


আর একটি আকর্ষণীয় তথ্য হ'ল সি # / .NET- null উপায়টি চিকিত্সা করা সর্বদা এক রকম হয় না যদি আপনি বিভিন্ন ডেটা ধরণের বিবেচনা করেন। উদাহরণ স্বরূপ:

int? x = 1;  //  string x = "1";
x = x + null + null;
Console.WriteLine((x==null) ? "<null>" : x.ToString());

বিবেচনা 1st লাইন কোড স্নিপেট এর: যদি xএকটি nullable পূর্ণসংখ্যা পরিবর্তনশীল (অর্থাত int?) মান ধারণকারী 1, তাহলে আপনি ফলাফলের পেয়ে থাকেন <null>ফিরে। যদি এটি মান সহ একটি স্ট্রিং হয় (মন্তব্যে দেখানো হয়) "1"তবে আপনি "1"তার চেয়ে ফিরে আসছেন <null>

এনবি এছাড়াও আকর্ষণীয়: আপনি যদি var x = 1;প্রথম লাইনের জন্য ব্যবহার করেন তবে আপনি রানটাইম ত্রুটি পেয়ে যাচ্ছেন। কেন? কারণ অ্যাসাইনমেন্টটি ভেরিয়েবলটি xডেটাটাইপগুলিতে পরিণত করবে int, যা কোনও পরিবর্তনযোগ্য নয়। সংকলকটি int?এখানে ধরে নিচ্ছে না এবং তাই যুক্ত হওয়া দ্বিতীয় লাইনে ব্যর্থ হয় null


2

nullএকটি স্ট্রিং যোগ করা সহজভাবে উপেক্ষা করা হয়। null(আপনার দ্বিতীয় উদাহরণে) কোনও বস্তুর উদাহরণ নয়, সুতরাং এটির কোনও ToString()পদ্ধতিও নেই। এটি কেবল আক্ষরিক।


1

কারণ string.Emptyএবং nullযখন আপনি কনক্রিট স্ট্রিংয়ের মধ্যে কোনও পার্থক্য নেই । আপনি string.Formatপাশাপাশি নাল পাস করতে পারেন । তবে আপনি একটি পদ্ধতিতে কল করার চেষ্টা করছেন null, যা সর্বদা একটিতে ফলাফল হয় NullReferenceExceptionএবং তাই একটি সংকলক ত্রুটি উত্পন্ন করে।
যদি কোনও কারণে আপনি সত্যিই এটি করতে চান তবে আপনি একটি এক্সটেনশন পদ্ধতি লিখতে পারেন, যা চেক করে nullএবং তারপরে ফিরে আসে string.Empty। তবে এর মতো একটি এক্সটেনশন কেবল তখনই ব্যবহার করা উচিত যখন সম্পূর্ণ প্রয়োজন (আমার মতে) opinion


0

সাধারণ হিসাবে: এটি নির্দিষ্টকরণের উপর নির্ভর করে প্যারামিটার হিসাবে নাল গ্রহণযোগ্য হতে পারে বা নাও পারে, তবে নালকে কোনও পদ্ধতিতে কল করা সর্বদা অবৈধ।


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

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