বস্তুগুলি সি #+ তে যেমন কখনও স্কোপের বাইরে যায় না। এগুলি আর ব্যবহার করা হয় না, তখন তাদের আবশ্যকভাবে আবর্জনা সংগ্রাহকরা তাদের সাথে ডিল করেন। এটি সি ++ এর চেয়ে আরও জটিল পদ্ধতি যেখানে ভেরিয়েবলের ব্যাপ্তি পুরোপুরি হ্রাসকারী। সিএলআর আবর্জনা সংগ্রহকারী সক্রিয়ভাবে তৈরি করা সমস্ত বস্তুর মধ্য দিয়ে যায় এবং যদি সেগুলি ব্যবহার করা হয় তবে তা কার্যকর হয়।
কোনও বস্তু একটি ফাংশনে "সুযোগের বাইরে" যেতে পারে তবে যদি এর মানটি ফিরে আসে, তবে জিসি কলিং ফাংশনটি রিটার্ন মান ধরে রাখে বা না তা সন্ধান করবে।
অবজেক্টের রেফারেন্স সেট null
করা অপ্রয়োজনীয় কারণ আবর্জনা সংগ্রহের কাজ করে কোন বস্তুটি অন্যান্য বস্তুগুলির দ্বারা রেফারেন্স করা হচ্ছে তা নিয়ে কাজ করে।
অনুশীলনে, আপনাকে ধ্বংস সম্পর্কে চিন্তা করার দরকার নেই, এটি কেবল কাজ করে এবং এটি দুর্দান্ত :)
Dispose
IDisposable
আপনি যখন তাদের সাথে কাজ শেষ করে তখন কার্যকর করে এমন সমস্ত অবজেক্টগুলিকে অবশ্যই ডাকা হবে । সাধারণত আপনি using
এই জাতীয় বস্তুগুলির সাথে একটি ব্লক ব্যবহার করবেন :
using (var ms = new MemoryStream()) {
//...
}
পরিবর্তনশীল সুযোগ এডিট করুন । ক্রেগ জিজ্ঞাসা করেছে ভেরিয়েবল স্কোপটি বস্তুর আজীবন কোনও প্রভাব ফেলবে কিনা। সিএলআরের সেই দিকটি সঠিকভাবে ব্যাখ্যা করতে, আমাকে সি ++ এবং সি # থেকে কয়েকটি ধারণার ব্যাখ্যা করতে হবে।
আসল পরিবর্তনশীল সুযোগ
উভয় ভাষায় ভেরিয়েবল কেবল একই স্কোপ হিসাবে এটি সংজ্ঞায়িত হিসাবে ব্যবহৃত হতে পারে - শ্রেণি, ফাংশন বা ব্রেস দ্বারা আবদ্ধ একটি বিবৃতি ব্লক। সূক্ষ্ম পার্থক্য, তবে, সি # তে, ভেরিয়েবলগুলি নেস্টেড ব্লকে পুনরায় সংজ্ঞায়িত করা যায় না।
সি ++ এ, এটি পুরোপুরি আইনী:
int iVal = 8;
//iVal == 8
if (iVal == 8){
int iVal = 5;
//iVal == 5
}
//iVal == 8
সি # তে, তবে আপনি এএ সংকলক ত্রুটি পান:
int iVal = 8;
if(iVal == 8) {
int iVal = 5; //error CS0136: A local variable named 'iVal' cannot be declared in this scope because it would give a different meaning to 'iVal', which is already used in a 'parent or current' scope to denote something else
}
আপনি উত্পন্ন এমএসআইএল-এর দিকে নজর রাখলে এটি অর্থবোধ করে - ফাংশনটির মাধ্যমে ব্যবহৃত সমস্ত ভেরিয়েবলগুলি ফাংশনের শুরুতে সংজ্ঞায়িত করা হয়। এই ফাংশনটি একবার দেখুন:
public static void Scope() {
int iVal = 8;
if(iVal == 8) {
int iVal2 = 5;
}
}
নীচে উত্পাদিত আইএল রয়েছে। মনে রাখবেন যে আইভাল 2, যদি ইফ ব্লকের ভিতরে সংজ্ঞায়িত হয় তবে ফাংশন স্তরে এটি সংজ্ঞায়িত হয়। কার্যকরভাবে এর অর্থ হ'ল সি # এর কেবল শ্রেণি এবং ফাংশন স্তরের সুযোগ রয়েছে যতক্ষণ না চলক জীবনকাল সম্পর্কিত।
.method public hidebysig static void Scope() cil managed
{
// Code size 19 (0x13)
.maxstack 2
.locals init ([0] int32 iVal,
[1] int32 iVal2,
[2] bool CS$4$0000)
//Function IL - omitted
} // end of method Test2::Scope
সি ++ সুযোগ এবং অবজেক্টের আজীবন
যখনই কোনও সি ++ পরিবর্তনশীল, স্ট্যাকের উপর বরাদ্দ করা হয়, সুযোগের বাইরে চলে যায় এটি ধ্বংস হয়ে যায়। মনে রাখবেন যে সি ++ এ আপনি স্ট্যাক বা গাদাতে অবজেক্ট তৈরি করতে পারেন। আপনি যখন এগুলি স্ট্যাকে তৈরি করেন, একবার মৃত্যুদন্ড কার্যকর করার সুযোগটি ছেড়ে যায়, তারা স্ট্যাকটি পপ করে ফেলে এবং ধ্বংস হয়ে যায়।
if (true) {
MyClass stackObj; //created on the stack
MyClass heapObj = new MyClass(); //created on the heap
obj.doSomething();
} //<-- stackObj is destroyed
//heapObj still lives
যখন সি ++ অবজেক্টগুলি গাদাতে তৈরি করা হয়, তাদের অবশ্যই স্পষ্টভাবে ধ্বংস করা উচিত, অন্যথায় এটি মেমরি ফাঁস হয়। স্ট্যাক ভেরিয়েবলের সাথে এ জাতীয় কোনও সমস্যা নেই।
সি # অবজেক্ট লাইফটাইম
সিএলআর-তে অবজেক্টস (অর্থাত্ রেফারেন্স প্রকারের) সর্বদা পরিচালিত হিপগুলিতে তৈরি হয়। এটি আবার অবজেক্ট ক্রিয়েশন সিনট্যাক্স দ্বারা আরও শক্তিশালী হয়। এই কোড স্নিপেট বিবেচনা করুন।
MyClass stackObj;
সি ++ MyClass
এ এটি স্ট্যাকের উপর একটি উদাহরণ তৈরি করবে এবং এর ডিফল্ট কনস্ট্রাক্টরকে কল করবে। সি # তে এটি শ্রেণীর একটি রেফারেন্স তৈরি করবে MyClass
যা কোনও কিছুর প্রতি নির্দেশ দেয় না। শ্রেণীর উদাহরণ তৈরির একমাত্র উপায় হ'ল new
অপারেটর ব্যবহার করে :
MyClass stackObj = new MyClass();
একটি উপায়ে, সি # অবজেক্ট অনেকগুলি অবজেক্টের মতো যা new
সি ++ তে সিনট্যাক্স ব্যবহার করে তৈরি করা হয় - সেগুলি হিপে তৈরি করা হয় তবে সি ++ অবজেক্টগুলির বিপরীতে এগুলি রানটাইম দ্বারা পরিচালিত হয়, সুতরাং আপনাকে সেগুলি ধ্বংস করার বিষয়ে চিন্তা করার দরকার নেই।
যেহেতু অবজেক্টগুলি সর্বদা হ'ল থাকে বস্তুর উল্লেখগুলি (অর্থাত্ পয়েন্টারগুলি) সুযোগের বাইরে চলে যায় তা মোটা হয়ে যায়। অবজেক্টের রেফারেন্সের সহজ উপস্থিতির চেয়ে কোনও বস্তু সংগ্রহ করতে হয় কিনা তা নির্ধারণে আরও বেশি কারণ রয়েছে।
সি # অবজেক্টের রেফারেন্স
জন স্কিটি জাভাতে অবজেক্টের রেফারেন্সের তুলনা করে স্ট্রিংয়ের টুকরাগুলির যা বেলুনের সাথে সংযুক্ত থাকে, যা বস্তু। একই উপমা সি # অবজেক্ট রেফারেন্সে প্রযোজ্য। তারা কেবল অস্তিত্বযুক্ত গাদা একটি অবস্থান নির্দেশ করে। সুতরাং, এটিকে শূন্য করাতে বস্তুর আজীবন কোনও তাত্ক্ষণিক প্রভাব পড়ে না, জিসি এটি "পপ" না করা পর্যন্ত বেলুনটির অস্তিত্ব অব্যাহত রয়েছে।
বেলুনের সাদৃশ্য অব্যাহত রেখে, এটি যৌক্তিক মনে হবে যে একবার বেলুনটির সাথে কোনও স্ট্রিং যুক্ত না হলে এটি ধ্বংস করা যায়। প্রকৃতপক্ষে হ'ল রেফারেন্স গণনা করা অবজেক্টগুলি অ-পরিচালিত ভাষাগুলিতে ঠিক কীভাবে কাজ করে। এই পদ্ধতিকে বাদ দিয়ে বিজ্ঞপ্তি রেফারেন্সের জন্য খুব ভাল কাজ করে না। দুটি বেলুনগুলি কল্পনা করুন যা স্ট্রিংয়ের সাথে একত্রে সংযুক্ত রয়েছে তবে বেলুনের অন্য কোনও কিছুর সাথে স্ট্রিং নেই। সরল রেফ গণনা সংক্রান্ত নিয়মের অধীনে, পুরো বেলুন গোষ্ঠীটি "এতিম" হওয়া সত্ত্বেও তারা উভয়ই বিদ্যমান রয়েছে।
.NET অবজেক্টগুলি অনেকটা ছাদের নীচে হিলিয়াম বেলুনগুলির মতো। যখন ছাদটি খোলা হয় (জিসি চালিত হয়) - অব্যবহৃত বেলুনগুলি ভেসে বেড়ায়, এমনকি সেখানে এমন একাধিক বেলুনের দল থাকতে পারে যা একসাথে জড়িত are
.NET GC প্রজন্মের GC এবং চিহ্ন এবং সুইপের সংমিশ্রণ ব্যবহার করে। জেনারেশনাল অ্যাপ্রোচটিতে রানটাইমের পক্ষে যুক্ত হওয়া বিষয়গুলিকে সর্বাধিক বরাদ্দ দেওয়া হয়েছে, কারণ এগুলি অব্যবহৃত হওয়ার সম্ভাবনা বেশি বেশি এবং চিহ্ন এবং সুইপ জড়িত রানটাইম পুরো অবজেক্টের গ্রাফের মধ্য দিয়ে যাওয়া এবং যদি অবজেক্ট গ্রুপ নেই তবে অবধি কাজ করা জড়িত। এটি পর্যাপ্তভাবে বিজ্ঞপ্তি নির্ভরতা সমস্যা নিয়ে কাজ করে।
এছাড়াও,। নেট জিসি অন্য থ্রেডে (তথাকথিত ফাইনালাইজার থ্রেড) চালায় কারণ এটি করার মতো কিছুটা আছে এবং মূল থ্রেডে করা আপনার প্রোগ্রামকে বাধা দেয়।