সি # কেন আপনাকে 'নাল নিক্ষেপ' করতে দেয়?


85

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

কেন এটি অনুমোদিত?

throw null;

এই স্নিপেটে, ধন্যবাদ 'প্রাক্তন' শূন্য নয়, তবে এটি কি কখনও হতে পারে?

try
{
  throw null;
}
catch (Exception ex)
{
  //can ex ever be null?

  //thankfully, it isn't null, but is
  //ex is System.NullReferenceException
}

9
আপনি কি নিশ্চিত যে আপনি নিজের থ্রোয়ের উপরে ফেলে একটি .NET ব্যতিক্রম (নাল রেফারেন্স) দেখছেন না?
micahtan

4
আপনি ভাবেন যে সংকলকটি অন্তত সরাসরি "নাল নিক্ষেপ করার চেষ্টা" সম্পর্কে একটি সতর্কতা উত্থাপন করবে;
অ্যান্ডি হোয়াইট

না আমি নিশ্চিত নই। ফ্রেমওয়ার্কটি খুব ভালভাবে আমার অবজেক্টের সাথে কিছু করার চেষ্টা করতে পারে এবং যখন এটি নাল হয়, তখন ফ্রেমওয়ার্কটি একটি "নাল রেফারেন্স ব্যতিক্রম" ছুড়ে দেয় .. তবে শেষ পর্যন্ত, আমি নিশ্চিত হতে চাই যে "প্রাক্তন" কখনই
নਾਲ

4
@ অ্যান্ডি: একটি সতর্কতা ল্যাংএজের অন্যান্য পরিস্থিতির জন্য অর্থবহ হতে পারে, তবে throwএকটি বিবৃতি যার উদ্দেশ্য প্রথমে ব্যতিক্রম ছড়িয়ে দেওয়া , একটি সতর্কতা খুব বেশি মূল্য দেয় না।
এমএমএক্স

@ মেহরদাদ - হ্যাঁ, তবে আমি সন্দেহ করি যে কোনও বিকাশকারী ইচ্ছাকৃতভাবে "নাল নিক্ষেপ" করবে এবং একটি নুলারফেরান এক্সেপশন দেখতে চায় কিনা doubt হতে পারে এটি একটি সম্পূর্ণ বিল্ড ত্রুটি হওয়া উচিত, যেমন একটি বিবৃতিতে একটি ভুল = তুলনা।
অ্যান্ডি হোয়াইট

উত্তর:


96

কারণ ভাষার স্পেসিফিকেশন System.Exceptionসেখানে প্রকারের একটি অভিব্যক্তি প্রত্যাশা করে (অতএব, nullসেই প্রসঙ্গে একটি বৈধ) এবং এই অভিব্যক্তিটি শূণ্য হতে সীমাবদ্ধ করে না। সাধারণভাবে, এই অভিব্যক্তির মান কিনা তা সনাক্ত করার কোনও উপায় nullনেই। এটি থামার সমস্যাটি সমাধান করতে হবে। রানটাইমটিকে nullযাইহোক মামলা মোকাবেলা করতে হবে । দেখা:

Exception ex = null;
if (conditionThatDependsOnSomeInput) 
    ex = new Exception();
throw ex; 

তারা অবশ্যই nullআক্ষরিক নিক্ষেপ করার সুনির্দিষ্ট কেসটিকে অকার্যকর করে তুলতে পারত তবে এতে তেমন কোনও উপকার হবে না, সুতরাং স্পেসিফিকেশন স্পেসটি কেন অপচয় করবে এবং সামান্য উপকারের জন্য ধারাবাহিকতা হ্রাস করবে?

দাবি অস্বীকার (এরিক লিপার্টের হাতে আমি চড় মারার আগে): এই নকশার সিদ্ধান্তের পিছনে যুক্তি সম্পর্কে এটি আমার নিজস্ব জল্পনা। অবশ্যই আমি ডিজাইনের বৈঠকে যাইনি;)


আপনার দ্বিতীয় প্রশ্নের উত্তর, একটি ক্যাচ ক্লজের মধ্যে থাকা এক্সপ্রেশন ভেরিয়েবলটি কখনই নালার হতে পারে: যদিও অন্যান্য # ভাষা nullব্যতিক্রম প্রচার করতে পারে কিনা তা নিয়ে সি # স্পেসিফিকেশন নীরব, যদিও এটি ব্যতিক্রম প্রচারের উপায়টিকে সংজ্ঞায়িত করে:

ব্যতিক্রমগুলির জন্য উপযুক্ত হ্যান্ডলারটি সনাক্ত করার জন্য ক্যাচ ক্লজগুলি, যদি কোনও হয় তবে উপস্থিতি অনুসারে পরীক্ষা করা হয়। ব্যতিক্রমের ধরণের বা ব্যতিক্রমের বেসের প্রকারটিকে নির্দিষ্ট করে এমন প্রথম ক্যাচটিকে ম্যাচ হিসাবে বিবেচনা করা হয়। একটি সাধারণ ক্যাচ ক্লজটি কোনও ব্যতিক্রম ধরণের জন্য একটি ম্যাচ হিসাবে বিবেচিত হয়। [...]

কারণ null, সাহসী বক্তব্যটি মিথ্যা। সুতরাং, সি # স্পিকার যা বলেছে তার ভিত্তিতে, আমরা বলতে পারি না যে অন্তর্নিহিত রানটাইমটি কখনই নালু ফেলবে না, আমরা নিশ্চিত হতে পারি যে এটি এমনকি যদি হয় তবে এটি কেবল জেনেরিক catch {}ধারা দ্বারা পরিচালিত হবে ।

সিএলআই-তে সি # বাস্তবায়নের জন্য, আমরা ইসিএমএ 335 উল্লেখ করতে পারি। এই দস্তাবেজটি সমস্ত ব্যতিক্রম সংজ্ঞায়িত করে যে সিএলআই অভ্যন্তরীণভাবে ছুঁড়ে ফেলে (যার মধ্যে কোনওটিই নয় null) এবং উল্লেখ করেছে যে ব্যবহারকারীর দ্বারা সংজ্ঞায়িত ব্যতিক্রম বস্তুগুলি throwনির্দেশের দ্বারা ছোঁড়া হয়েছে । সেই নির্দেশের বিবরণটি সি # throwস্টেটমেন্টের সাথে কার্যত অভিন্ন (ব্যতীত এটি বস্তুর প্রকারকে সীমাবদ্ধ করে না System.Exception):

বর্ণনা:

throwনির্দেশ ব্যতিক্রম বস্তু (টাইপ ছোঁড়ার Oস্ট্যাক) এবং স্ট্যাকের বের করে দেয়। ব্যতিক্রম প্রক্রিয়াটির বিশদগুলির জন্য, পার্টিশন I দেখুন
[ শেষ নোট]

ব্যতিক্রম:

System.NullReferenceExceptionযদি objহয় তবে ফেলে দেওয়া হয় null

সঠিকতা:

সঠিক সিআইএল নিশ্চিত করে যে বস্তুটি সর্বদা হয় nullবা কোনও বস্তুর রেফারেন্স (যেমন, টাইপের O)।

আমি বিশ্বাস করি যে ধরা ব্যতিক্রমগুলি কখনই নয় এই সিদ্ধান্তে যথেষ্ট null


আমি মনে করি যে এটি সর্বোত্তমভাবে করতে পারে যেমন স্পষ্ট বাক্যাংশ যেমন নিষিদ্ধ করা throw null;
হতাশিত

7
প্রকৃতপক্ষে, কোনও বস্তু নিক্ষেপ করা সম্পূর্ণরূপে (সিএলআর তে) সম্ভব যা সিস্টেম থেকে উত্তরাধিকারসূত্রে আসে না x আমি যতদূর জানি সি # তে এটি করতে পারবেন না, তবে এটি আইএল, সি ++ / সিএলআর ইত্যাদির মাধ্যমে করা যেতে পারে আরও তথ্যের জন্য এমএসডিএন.এম.সাইক্রোসফটকম /en-us/library/ms404228.aspx দেখুন ।
টেকনোফিল

@ টেকনোফিল: হ্যাঁ আমি এখানে ভাষা সম্পর্কে কথা বলছি। সি # তে, অন্য ধরণের একটি ব্যতিক্রম ছুঁড়ে ফেলা সম্ভব নয় তবে জেনেরিক catch { }ধারাটি ব্যবহার করে এটি ধরা সম্ভব ।
এমএমএক্স

4
যদিও কোনও সংকলক throwযার যুক্তি নাল মান হিসাবে গ্রহণ করতে অস্বীকার করবেন তা বোঝা যায় না, তবে এটি বোঝায় না যে এটি throw nullআইনী হতে হবে। একটি সংকলক জোর দিতে পারে যে একটি throwযুক্তির একটি বোধগম্য শ্রেণির ধরন রয়েছে। মত (System.InvalidOperationException)nullপ্রকাশটি সংকলনের সময় বৈধ হওয়া উচিত (এটি কার্যকর করে একটি হওয়া উচিত NullReferenceException) তবে এর অর্থ এই নয় যে একটি টাইপযুক্ত nullগ্রহণযোগ্য হবে।
সুপারক্যাট

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

29

স্পষ্টতই, আপনি নাল নিক্ষেপ করতে পারেন, তবে এটি এখনও কোথাও একটি ব্যতিক্রম রূপান্তরিত হয়েছে।

nullএকটি (সম্পূর্ণ সম্পর্কহীন) নাল রেফারেন্স ব্যতিক্রমের কোনও বস্তুর ফলাফল ছুঁড়ে ফেলার চেষ্টা করা হচ্ছে ।

আপনাকে কেন ফেলে দিতে দেওয়া nullহচ্ছে তা জিজ্ঞাসা করা আপনাকে কেন এটি করার অনুমতি দেয় তা জিজ্ঞাসার মতো:

object o = null;
o.ToString();

5

এখান থেকে নেওয়া :

আপনি যদি নিজের সি # কোডে এই এক্সপ্রেশনটি ব্যবহার করেন তবে এটি একটি নুলারফেরান এক্সেপশন নিক্ষেপ করবে। এটি কারণ থ্রো-বিবৃতিতে এর একক প্যারামিটার হিসাবে এক্সপশন টাইপের একটি অবজেক্টের প্রয়োজন। কিন্তু এই খুব অবজেক্ট আমার উদাহরণে নাল।


5

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

সুতরাং, যদিও আমরা সি # থেকে নাল ফেলে দিতে পারি না, নেদারওয়ার্ল্ড নাল ফেলে দিতে পারে, সুতরাং আপনার বহিরাগতের ক্যাচ (এক্সভেশন প্রাক্তন) এটি গ্রহণের জন্য আরও ভাল প্রস্তুত থাকুন। শুধু এফওয়াইআই।


4
মজাদার. আপনি কি কিছু কোড পোস্ট করতে পারেন বা নীচে আপনার গভীরতায় বসে এটি কি করছে তা ছড়িয়ে দিতে পারেন?
পিটার লিলভোল্ড

আমি এটি বলতে পারব না এটি সিএলআর বাগ কিনা ... .NET এর সাহসিকতায় কী রুদ্ধ হয়েছে তা খুঁজে বের করা শক্ত এবং কেন আপনি কল স্ট্যাক বা অন্য কোনও ক্লু চালিয়ে যেতে ব্যর্থ হন না কেন? আমি কেবল জানি যে আমার বাহ্যিকতম ধরা এখন এটি ব্যবহার করার আগে নাল ব্যতিক্রম যুক্তিটি পরীক্ষা করে।
ব্রায়ান কেনেডি

4
আমি সন্দেহ করি এটি একটি সিএলআর বাগ, বা খারাপ যাচাইযোগ্য কোডের কারণে নয়। সঠিক সিআইএল কেবল একটি নন-নাল অবজেক্ট, বা নাল (যা নুলরফারেন্স এক্সেকশন হয়ে যায়) ফেলে দেবে।
ডেমি

আমি এমন একটি পরিষেবাও ব্যবহার করছি যা শূন্য ব্যতিক্রমটি ফিরিয়ে দিচ্ছে। আপনি কি কখনও বুঝতে পেরেছিলেন যে নাল ব্যতিক্রমটি কীভাবে নিক্ষেপ করা হচ্ছে?
themiDdlest

2

আমি মনে করি সম্ভবত আপনি পারবেন না - যখন আপনি নাল ছুঁড়ে ফেলার চেষ্টা করবেন, এটি পারবেন না, সুতরাং এটি ত্রুটির ক্ষেত্রে যা করা উচিত তা করে, যা একটি নাল রেফারেন্স ব্যতিক্রম নিক্ষেপ করে। সুতরাং আপনি আসলে নাল নিক্ষেপ করছেন না, আপনি নাল নিক্ষেপ করতে ব্যর্থ হচ্ছেন, যার ফলস্বরূপ একটি নিক্ষেপ হবে।


2

".. ধন্যবাদ দেওয়ার জন্য 'প্রাক্তন' জবাব দেওয়ার চেষ্টা করা শূন্য নয়, তবে কি কখনও তা হতে পারে?":

যেহেতু আমরা যুক্তিযুক্তভাবে ব্যতিক্রম বাতিল করতে পারি না যা নাল, সুতরাং একটি ক্যাচ ক্লজটি কখনই শূন্য নয় এমন একটি ব্যতিক্রমও ধরতে হবে না। সুতরাং, প্রাক্তন কখনও নাল হতে পারে না।

আমি এখন দেখছি যে এই প্রশ্নটি ইতিমধ্যে জিজ্ঞাসা করা হয়েছে ।


@ ব্রায়ান কেনেডি আমাদের উপরে তার মন্তব্যে বলেছেন যে আমরা শূন্য করতে পারি।
অধ্যাপক

@ টিভিডি 1 - আমি মনে করি এখানে পার্থক্যটি হ্যাঁ, আপনি কার্যকর করতে পারেন throw null। তবে এটি একটি ব্যতিক্রম নিক্ষেপ করবে না । বরং, যেহেতু throw nullনাল রেফারেন্সে পদ্ধতিগুলি চাওয়ার চেষ্টা করা হয়, এটি পরবর্তী সময়ে রানটাইমটিকে একটি নন-নাল উদাহরণ নিক্ষেপ করতে বাধ্য করে NullReferenceException
পিটার লিলিভল্ড

1

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

ঠিক এটি ঘটছে কিনা তা নিশ্চিত নয়, তবে এটি ঘটনাকে ব্যাখ্যা করে।

এটি সত্য বলে ধরে নিচ্ছি (এবং আমি নাল নিক্ষেপের চেয়ে নাল হয়ে যাওয়ার আরও ভাল উপায় ভাবতে পারি না;), এর অর্থ এই হবে যে প্রাক্তনটি সম্ভবত নাল হতে পারে না।


-1

পুরানো সি #:

এই বাক্য গঠন বিবেচনা করুন:

public void Add<T> ( T item ) => throw (hashSet.Add ( item ) ? null : new Exception ( "The item already exists" ));

আমি মনে করি এটি এর চেয়ে আরও ছোট:

public void Add<T> ( T item )
{
    if (!hashSet.Add ( item ))
        throw new Exception ( "The item already exists" );
}

এটি আমাদের কি বলল?
bornfromanegg

প্রসঙ্গত, আপনার সংক্ষিপ্তসারটির সংজ্ঞা কী তা আমি নিশ্চিত নই, তবে আপনার দ্বিতীয় উদাহরণে কম অক্ষর রয়েছে।
bornfromanegg

@bornfromanegg প্রথম 1 ম ইন্ডেল ইনড ইনড, তাই এটি অবশ্যই সংক্ষিপ্ত। আমি যা বলতে চাইছিলাম তা হ'ল আপনি শর্তের উপর নির্ভর করে কোনও ত্রুটি ফেলতে পারেন। Ditionতিহ্যগতভাবে, আপনি ২ য় উদাহরণ পছন্দ করেন তবে "নাল নিক্ষেপ" যেহেতু কোনও কিছুই ফেলে দেয় না, আপনি প্রথম উদাহরণের মতো দেখতে দ্বিতীয় উদাহরণটি ইনলাইন করতে পারেন। এছাড়াও, প্রথম উদাহরণে ২ য় অক্ষরের চেয়ে কম অক্ষর রয়েছে
আরটিউইন এনফেন্ডজহিয়ান

"নাল নিক্ষেপ" একটি নালরফেরেন্স ব্যতিক্রম ছোঁড়ে। যার অর্থ আপনার প্রথম উদাহরণ সর্বদা একটি ব্যতিক্রম ছুঁড়ে ফেলবে ।
bornfromanegg

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