একটি আর্গুমেন্ট নাল এক্সসেপশন নিক্ষেপ কীভাবে সহায়তা করে?


27

ধরা যাক আমার একটি পদ্ধতি রয়েছে:

public void DoSomething(ISomeInterface someObject)
{
    if(someObject == null) throw new ArgumentNullException("someObject");
    someObject.DoThisOrThat();
}

আমি বিশ্বাস করতে প্রশিক্ষিত হয়েছি যে এটি নিক্ষেপ ArgumentNullExceptionকরা "সঠিক" তবে একটি "অবজেক্ট রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি" ত্রুটির অর্থ আমার একটি বাগ রয়েছে।

কেন?

আমি জানি যে আমি যদি রেফারেন্সটি ক্যাশে করেছিলাম someObjectএবং এটি পরে ব্যবহার করছি, তবে পাস করার সময় নালিশতা যাচাই করা ভাল এবং তাড়াতাড়ি ব্যর্থ হওয়া ভাল। যাইহোক, আমি যদি পরের লাইনে এটি ডিগ্রিফার করছি তবে আমাদের চেকটি কেন করা উচিত? এটি একরকম বা অন্যভাবে ব্যতিক্রম ছুঁড়ে ফেলছে।

সম্পাদনা করুন :

এটি আমার কাছে কেবল ঘটেছে ... অবহেলিত শূন্যতার ভয় কি সি ++ এর মতো ভাষা থেকে আসে যা আপনার জন্য পরীক্ষা করে না (যেমন এটি কেবল মেমরির অবস্থান শূন্য + পদ্ধতিতে অফসেটে কিছু পদ্ধতি চালানোর চেষ্টা করে)?


ব্যতিক্রমটি সুস্পষ্ট করা নিশ্চিত করতে সহায়তা করে যে ত্রুটির সম্ভাবনা রয়েছে, যা ডকুমেন্টেশনে সরাসরি লক্ষ করা যায়।
zzzzBov

উত্তর:


34

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

তদতিরিক্ত, পরবর্তী রক্ষণাবেক্ষণকারীরা আরও বেশি কি করছেন? প্রথম অস্তিত্বের আগে যদি তারা কোড যুক্ত করে, বা কেবল কোড যুক্ত করে এবং পরে কোনও নালরফারেন্সেক্সেক্সেশন নিক্ষেপ করার অনুমতি দেয় তবে যুক্তি নলএক্সেপশন যুক্ত করুন?


এক্সটেনশান দ্বারা, যদি এটি একটি সর্বজনীন পদ্ধতি, বা একটি জন-সরকারী শ্রেণিতে একটি সরকারী পদ্ধতি ছিল, আপনি নাল চেক করার কোনও ভাল কারণ আছে বলে মনে করেন না?
স্কট হুইটলক

আমি সাধারণত এই চেকগুলিকে ব্যক্তিগত পদ্ধতিতে যোগ করি না, তবে আমি এখনও তাদের ব্যক্তিগত ক্লাসের পাবলিক পদ্ধতিতে যুক্ত হতে পারি consistent ব্যক্তিগত পদ্ধতির জন্য, আমি এমন একটি ধারণা তৈরি করি যে যুক্তিগুলি কিছু পাবলিক-কল পর্যায়ে আগে বৈধ করা হয়েছিল।
ম্যাট এইচ

54

আমি বিশ্বাস করতে প্রশিক্ষিত হয়েছি যে আর্গুমেন্টনালএক্সসেপশন নিক্ষেপ করা "সঠিক" তবে একটি "অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি" ত্রুটির অর্থ আমার একটি বাগ রয়েছে। কেন?

ধরুন আমি আপনার M(x)যে লিখিত পদ্ধতিটি কল করেছি । আমি নাল পাস। নামটি "x" এ সেট করে আমি একটি আর্গুমেন্টনাল এক্সসেপশন পেয়েছি। এই ব্যতিক্রমটি স্পষ্টতই বোঝা যাচ্ছে যে আমার একটি বাগ আছে; আমি এক্স এর জন্য নাল পাস করা উচিত ছিল না।

ধরুন আমি আপনার দ্বারা লিখিত একটি পদ্ধতি এম কল করি। আমি নাল পাস। আমি একটি নাল দেরেফ ব্যতিক্রম পাই। আমি কীভাবে জানতে পারি যে আমার একটি বাগ আছে বা আপনার কোনও ত্রুটি বা তৃতীয় পক্ষের লাইব্রেরি রয়েছে যা আপনি আমার পক্ষ থেকে ডাকলেন তাতে একটি বাগ রয়েছে? আমাকে আমার কোড ঠিক করতে হবে বা আপনাকে ঠিক করার জন্য আপনাকে কল করতে হবে কিনা সে সম্পর্কে আমি কিছুই জানি না।

ব্যতিক্রম উভয়ই বাগের সূচক; উভয়ই কখনও উত্পাদন কোডে নিক্ষেপ করা উচিত নয় । প্রশ্নটি হ'ল কোন ব্যতিক্রমটি ডিবাগিং করা ব্যক্তির সাথে বাগের সাথে আরও ভাল যোগাযোগ করে ? নাল ডেরেফ ব্যতিক্রম আপনাকে প্রায় কিছুই বলে না; যুক্তি নাল ব্যতিক্রম আপনাকে অনেক কিছু বলে। আপনার ব্যবহারকারীদের প্রতি সদয় হন; ব্যতিক্রমগুলি ছুঁড়ে ফেলুন যা তাদের ভুল থেকে শিখতে সক্ষম করে।


আমি নিশ্চিত নই যে আমি বুঝতে পেরেছি "neither should ever be thrown in production code"কী অন্যান্য কোড / পরিস্থিতি তারা ব্যবহার করবে? সেগুলি কি এর মতো সংকলন করা উচিত Debug.Assert? বা আপনার অর্থ এগুলি এপিআই থেকে বের করে দেওয়া হবে না?
স্টুপারউসার

6
@ স্টুপার ইউজার: আমি মনে করি আপনি কী বোঝাতে চেয়েছিলেন তা ভুল বুঝেছি কারণ আমি এটি একটি বিভ্রান্তিমূলকভাবে লিখেছিলাম। আপনি উচিত আছে throw new ArgumentNullExceptionআপনার উৎপাদন কোড, এবং এটা একটি পরীক্ষা মামলার বাইরে চালানো উচিত । ব্যতিক্রমটি আসলে কখনও ছুঁড়ে ফেলা উচিত নয় কারণ কলারের কাছে কখনও ত্রুটি থাকা উচিত নয়।
এরিক লিপার্ট

1
কার কাছে ত্রুটি রয়েছে তা কেবল এটিই যোগাযোগ করে না, বাগটি কোথায় রয়েছে তা যোগাযোগ করে। যদিও উভয় অঞ্চলই আমার, এটি ঠিক কী পরিবর্তনশীল নাল ছিল তা বোঝা সর্বদা সহজ নয়।
ওহাদ স্নাইডার

5

মুল বক্তব্যটি হ'ল আপনার কোডটি অর্থপূর্ণ কিছু করা উচিত।

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

একটি ArgumentNullExceptionঅর্থবহ, কারণ এটি আমাকে বলে: তর্কটি someObjectছিল বলে অপারেশন ব্যর্থ হয়েছিল null। এটি বের করার জন্য আমার আপনার কোডটি দেখার দরকার নেই।

এই ব্যতিক্রম উত্থাপনের অর্থ হ'ল আপনি স্পষ্টভাবে পরিচালনা করছেন nullযদিও এটি করার একমাত্র উপায় আপনি এটি পরিচালনা করতে পারবেন না, কেবল কোড ক্রাশের সম্ভাব্য অর্থ হতে পারে, আপনি সম্ভবত নাল পরিচালনা করতে সক্ষম হবেন , কিন্তু মামলাটি বাস্তবায়ন করতে ভুলে গেছি।

ব্যতিক্রমগুলির বিষয়টি হ'ল ব্যর্থতার ক্ষেত্রে তথ্য যোগাযোগ করা, যা ব্যর্থতা থেকে পুনরুদ্ধার করার জন্য রানটাইমে পরিচালনা করা যেতে পারে বা ডিবাগ সময়ে কী ভুল হয়েছে তা আরও ভালভাবে বুঝতে।


2

আমি বিশ্বাস করি এর একমাত্র সুবিধা হ'ল আপনি বাদে আরও ভাল ডায়াগনস্টিক সরবরাহ করতে পারেন। এটি আপনারা জানেন যে ফাংশনটির কলারটি নাল ছাড়ছে, আপনি যদি ডিটারেফারেন্সটি নিক্ষেপ করতে দেন তবে আপনি নিশ্চিত হন না যে কলারটি ভুল ডেটা পেরিয়েছেন বা ফাংশনে নিজেই কোনও বাগ আছে কিনা you

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


1

আমি বিশ্বাস করতে প্রশিক্ষিত হয়েছি যে আর্গুমেন্টনালএক্সসেপশন নিক্ষেপ করা "সঠিক" তবে একটি "অবজেক্টের রেফারেন্স কোনও অবজেক্টের উদাহরণে সেট করা হয়নি" ত্রুটির অর্থ আমার একটি বাগ রয়েছে।

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

অপারেটিং সিস্টেমের সাথে সম্পর্কিত এমন ApplicationExceptionএকটি সাধারণ বনাম আপনার আবেদনের সাথে সম্পর্কিত কারণগুলিও Exception। যে ধরণের ব্যতিক্রম নিক্ষেপ করা হয়েছে তা ইঙ্গিত দেয় যেখানে ব্যতিক্রমটির উত্স।

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

পরিশেষে, পরিস্থিতি পরিচালনা করতে কলারের ক্ষমতাকে অবহেলা করবেন না। তাদের আরও সুনির্দিষ্ট ব্যতিক্রম দিয়ে, ArgumentExceptionতারা আরও সাধারণের আগে এই ত্রুটিটি পরিচালনা করতে এমনভাবে তাদের চেষ্টা / ক্যাপচারটি তৈরি NullReferenceExceptionকরতে পারে যা অন্য কোথাও ঘটে এমন কোনও কারণের কারণে হতে পারে, যেমন কনস্ট্রাক্টর ভেরিয়েবল আরম্ভ করতে ব্যর্থ হয়।


1

চেকটি যা ঘটছে তা আরও স্পষ্ট করে তোলে, তবে আসল সমস্যাটি এই জাতীয় কোড সহ আসে (স্বীকৃত) উদাহরণ:

public void DoSomething(Foo someOtherObject, ISomeInterface someObject)
{
    someOtherObject.DoThisOrThat(this, someObject);
}

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

সাধারণভাবে এই ধরণের জিনিসটির সাথে সামঞ্জস্য থাকা এবং সর্বদা নাল চেক যুক্ত করা ভাল - যা কেস-বাই-কেস ভিত্তিতে বাছাই করা এবং বেছে নেওয়ার চেয়ে যদি কেউ অনুপস্থিত থাকে তবে তা চিহ্নিত করা সহজ করে তোলে (ধরে নিবেন যে আপনি জানেন যে নাল সর্বদা অবৈধ)।


1

বিবেচনা করার আরেকটি কারণ হ'ল নাল অবজেক্টটি ব্যবহার করার আগে যদি কিছু প্রক্রিয়াজাতকরণ ঘটে?

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

সিড সিড সিড সিড পিআইডি সিড পিড সিড পিআইডি সিড সিড পিড

এবং এই ভিবি ফাংশন ফাইলটিতে রেকর্ড লিখুন:

Sub WriteRecord(Company As CompanyInfo, Person As PersonInfo)
    Using File As New StringWriter(DataFileName)
        File.Write(Company.ID)
        File.Write(Person.ID)
    End Using
End Sub

যদি Personনাল রেফারেন্স হয় তবে লাইনটি File.Write(Person.ID)একটি ব্যতিক্রম ছুঁড়ে দেবে। সফ্টওয়্যারটি ব্যতিক্রমটি ধরে ফেলতে পারে এবং পুনরুদ্ধার করতে পারে তবে এটি একটি সমস্যা ছেড়ে দেয়। কোনও সংস্থার আইডি কোনও যুক্ত ব্যক্তির আইডি ছাড়া লেখা হয়েছে। যদি সত্য হয়, আপনি যখন এই ফাংশনটি কল করবেন তখন আপনি এমন একটি সংস্থার আইডি রাখবেন যেখানে আগের ব্যক্তির আইডি প্রত্যাশিত ছিল। সেই রেকর্ডটি ভুল হওয়ার পাশাপাশি, পরবর্তী প্রতিটি রেকর্ডে একটি ব্যক্তির আইডি থাকবে যার পরে একটি কোম্পানির আইডি থাকবে, যা ভুল পথে the

সিড সিড সিড সিড সিড সিড সিড সিড সিড সিড সিড পিড সিড

ফাংশনটির শুরুতে প্যারামিটারগুলি বৈধকরণের মাধ্যমে, পদ্ধতিটি ব্যর্থ হওয়ার গ্যারান্টিযুক্ত আপনি কোনও প্রক্রিয়া ঘটতে বাধা দেন।

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