আমাদের কেন সি # তে বক্সিং এবং আনবক্সিংয়ের দরকার?


323

আমাদের কেন সি # তে বক্সিং এবং আনবক্সিংয়ের দরকার?

বক্সিং এবং আনবক্সিং কী তা আমি জানি তবে আমি এর আসল ব্যবহার বুঝতে পারি না। কেন এবং কোথায় আমি এটি ব্যবহার করা উচিত?

short s = 25;

object objshort = s;  //Boxing

short anothershort = (short)objshort;  //Unboxing

উত্তর:


480

কেন

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

এইভাবে ভেবে দেখুন। আপনার oটাইপের একটি ভেরিয়েবল রয়েছে object। এবং এখন আপনার একটি আছে intএবং আপনি এটি toোকাতে চান ooএটি কোথাও কোনও কিছুর intরেফারেন্স এবং জোরালোভাবে কোথাও কোনও কিছুর রেফারেন্স নয় (সর্বোপরি এটি কেবল একটি সংখ্যা)। সুতরাং, আপনি যা করেন তা হ'ল: আপনি এমন একটি নতুন তৈরি করেন objectযা স্টোর সংরক্ষণ করতে পারে intএবং তারপরে আপনি সেই অবজেক্টের জন্য একটি রেফারেন্স বরাদ্দ করেন o। আমরা এই প্রক্রিয়াটিকে "বক্সিং" বলি।

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

আমার এটি কোথায় ব্যবহার করা উচিত

উদাহরণস্বরূপ, পুরানো সংগ্রহের ধরণটি ArrayListকেবলমাত্র objectএস। অর্থাত্‍, এটি কেবল কোথাও যে কোনও স্থানে থাকা কিছু কিছু উল্লেখের জন্য রেফারেন্স সঞ্চয় করে। বক্সিং না করে আপনি এ intজাতীয় সংগ্রহ করতে পারবেন না । কিন্তু বক্সিং দিয়ে, আপনি পারেন।

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

এটি সঠিক:

double e = 2.718281828459045;
int ee = (int)e;

এটি হবে না:

double e = 2.718281828459045;
object o = e; // box
int ee = (int)o; // runtime exception

পরিবর্তে আপনি এটি করতে হবে:

double e = 2.718281828459045;
object o = e; // box
int ee = (int)(double)o;

প্রথম আমরা আছে স্পষ্টভাবে unbox করার double( (double)o) এবং তারপর একটি যে নিক্ষেপ int

নিম্নলিখিত ফলাফল কি:

double e = 2.718281828459045;
double d = e;
object o1 = d;
object o2 = e;
Console.WriteLine(d == e);
Console.WriteLine(o1 == o2);

পরের বাক্যে যাওয়ার আগে এক সেকেন্ডের জন্য এটি সম্পর্কে ভাবেন।

আপনি যদি বলেন Trueএবং Falseদুর্দান্ত! কিসের অপেক্ষা? এর কারণ ==রেফারেন্সের ধরণগুলিতে রেফারেন্স-সাম্যতা ব্যবহার করা হয় যা রেফারেন্সগুলি সমান কিনা তা পরীক্ষা করে, অন্তর্নিহিত মানগুলি সমান না হলে নয়। এটি করা একটি বিপজ্জনকভাবে সহজ ভুল। সম্ভবত আরও সূক্ষ্ম

double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);

ছাপবেও False!

বলা ভাল:

Console.WriteLine(o1.Equals(o2));

যা তখন, ধন্যবাদ, মুদ্রণ করবে True

একটি শেষ সূক্ষ্মতা:

[struct|class] Point {
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Point p = new Point(1, 1);
object o = p;
p.x = 2;
Console.WriteLine(((Point)o).x);

আউটপুট কি? এটা নির্ভর করে! যদি Pointহয় structতবে আউটপুট হয় 1তবে যদি Pointহয় classতবে আউটপুট হয় 2! একটি বক্সিং রূপান্তর আচরণের পার্থক্য ব্যাখ্যা করে বক্স করা মানের একটি অনুলিপি তৈরি করে।


@ জেসন আপনার কি বলতে চাইছেন যে আমাদের যদি আদিম তালিকা থাকে তবে কোনও বক্সিং / আনবক্সিং ব্যবহার করার কোনও কারণ নেই?
পেসেরিয়র

আপনি "আদিম তালিকা" বলতে কী বুঝছেন তা আমি নিশ্চিত নই।
জেসন

3
আপনি কর্মক্ষমতা প্রভাব অনুগ্রহ করে কথা গেল boxingএবং unboxing?
কেভিন মেরেডিথ

@KevinMeredith সেখানে এবং আনবক্সিং অপারেশন বক্সিং জন্য কর্মক্ষমতা সম্পর্কে একটি মৌলিক ব্যাখ্যা msdn.microsoft.com/en-us/library/ms173196.aspx
InfZero

2
দুর্দান্ত উত্তর - আমি সুনামের বইয়ে পড়েছি এমন বেশিরভাগ ব্যাখ্যা থেকে ভাল।
ফ্রেডএম

58

.NET ফ্রেমওয়ার্কে, দুটি ধরণের প্রকার রয়েছে - মানের ধরণ এবং রেফারেন্স প্রকার। এটি ওও ভাষাগুলিতে তুলনামূলকভাবে সাধারণ।

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

এখন, পুরানো দিনগুলিতে (মাইক্রোসফট.নেট এর 1.0), নতুন এই জেনারিক হুল্লাবালু ছিল না। আপনি এমন কোনও পদ্ধতি লিখতে পারেন নি যার একটি মান যুক্তি এবং একটি রেফারেন্স ধরণের পরিষেবা দিতে পারে এমন একক যুক্তি ছিল। এটা বহুবিজ্ঞানের লঙ্ঘন। সুতরাং বক্সিং একটি বস্তুর মধ্যে একটি মান টাইপ জোর করার উপায় হিসাবে গৃহীত হয়েছিল।

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

বক্সিং এটি হতে বাধা দেয়। আর এ কারণেই ব্রিটিশরা বক্সিং দিবস পালন করে।


1
জেনেরিক্সের আগে অটো-বক্সিং করার জন্য অনেক কিছু করা দরকার ছিল; জেনেরিকের অস্তিত্বের ভিত্তিতে, তবে, যদি এটি পুরানো কোডের সাথে সামঞ্জস্য বজায় রাখার প্রয়োজন না হয়, তবে আমি মনে করি impুকিয়ে দেওয়া বক্সিং রূপান্তর ছাড়াই নেট ভাল better একটি মান ধরণের পছন্দ List<string>.Enumeratorকরা কাস্ট করা একটি IEnumerator<string>অবজেক্ট উত্পন্ন করে যা বেশিরভাগ শ্রেণীর ধরণের মতো আচরণ করে তবে একটি ভাঙ্গা Equalsপদ্ধতিতে। কাস্ট List<string>.Enumeratorকরার একটি আরও ভাল উপায় IEnumerator<string>হ'ল একটি কাস্টম রূপান্তর অপারেটরকে কল করা, তবে একটি অন্তর্নিহিত রূপান্তরটির অস্তিত্ব তা আটকায়।
সুপারক্যাট

42

এটি বোঝার সর্বোত্তম উপায় হ'ল সি-বিল্ড করা নিম্ন-স্তরের প্রোগ্রামিং ভাষাগুলি।

সি এর মতো সর্বনিম্ন স্তরের ভাষায়, সমস্ত ভেরিয়েবল এক জায়গায় যায়: স্ট্যাক। প্রতিবার আপনি ভেরিয়েবল ঘোষণা করলে এটি স্ট্যাকের দিকে যায়। এগুলি কেবল একটি বুল, বাইট, 32-বিট ইন্টি, 32-বিট ইউন্ট ইত্যাদির মতো আদিম মান হতে পারে The স্ট্যাক উভয়ই সহজ এবং দ্রুত। ভেরিয়েবলগুলি যুক্ত হওয়ার সাথে সাথে তারা কেবল একটির উপরে উঠে যায়, সুতরাং প্রথমে আপনি 0x00 বলে বসেন, পরেরটি 0x01, পরেরটি 0x02 এ র‌্যামে ইত্যাদি addition সময়, যাতে আপনি এমনকি প্রোগ্রাম চালানোর আগে তাদের ঠিকানা জানা যাবে।

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

পয়েন্টারগুলির সাথে ডিল করা শক্ত। এগুলি মেমরি ফাঁস, বাফারকে ছাড়িয়ে যাওয়ার এবং হতাশার কারণ। সি # উদ্ধার করতে।

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

কোডারের দৃষ্টিকোণ থেকে এই 2 মুলত পৃথক পৃথক ধারণাগুলির (এবং স্টোরেজ করার কৌশলগুলি) এর মধ্যে মিথস্ক্রিয়া রাখার স্বার্থে, মান টাইপগুলি যে কোনও সময় বক্স করা যায়। বক্সিংয়ের কারণে স্ট্যাক থেকে মানটি অনুলিপি করা হয়, একটি বস্তুতে রাখা হয় এবং গাদাতে রাখা হয় - আরও ব্যয়বহুল, তবে, রেফারেন্স বিশ্বের সাথে তরল পদক্ষেপ inte অন্যান্য উত্তরগুলি নির্দেশ করে, এটি যখন ঘটবে উদাহরণস্বরূপ:

bool b = false; // Cheap, on Stack
object o = b; // Legal, easy to code, but complex - Boxing!
bool b2 = (bool)o; // Unboxing!

বক্সিংয়ের সুবিধার একটি দৃ strong় উদাহরণ হ'ল নালার জন্য একটি চেক:

if (b == null) // Will not compile - bools can't be null
if (o == null) // Will compile and always return false

আমাদের অবজেক্ট o স্ট্যাকের প্রযুক্তিগতভাবে একটি ঠিকানা যা আমাদের বুলের একটি অনুলিপি নির্দেশ করে, যা হিপে অনুলিপি করা হয়েছে। আমরা নাল জন্য ও পরীক্ষা করতে পারি কারণ বুলটি বক্স হয়ে গেছে এবং সেখানে রাখা হয়েছে।

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

বক্সিং প্রয়োজন এমন historicalতিহাসিক সি # কাঠামোর একটি অ-নিষ্ক্রিয় তালিকা, যা আপনার এড়ানো উচিত:

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

  • পুরাতন থ্রেডিং এবং টাইমার মডেলগুলি তাদের প্যারামিটারগুলিতে একটি বক্সকে বাধ্য করেছিল তবে এ্যাসিএনসি / অপেক্ষার জায়গায় প্রতিস্থাপন করা হয়েছে যা আরও পরিষ্কার এবং আরও কার্যকর more

  • । নেট 1.1 সংগ্রহগুলি পুরোপুরি বক্সিংয়ের উপর নির্ভর করে, কারণ তারা জেনারিক্সের আগে এসেছিল। এটি এখনও সিস্টেমে.কলেশনগুলিতে লাথি মারছে। যে কোনও নতুন কোডে আপনার সিস্টেমের সংগ্রহ থেকে সংগ্রহ করা উচিত Col সংগ্রহগুলি G জেনেরিক, যা বক্সিং এড়ানো ছাড়াও আপনাকে আরও শক্তিশালী টাইপ-সুরক্ষা সরবরাহ করে

আপনার মূল্য প্রকারকে অবজেক্ট হিসাবে ঘোষণা করা বা পাস করা এড়াতে হবে, যদি না আপনি বক্সিংয়ের উপরোক্ত historicalতিহাসিক সমস্যাগুলি মোকাবিলা করতে না চান এবং আপনি যদি জানেন যে এটি যেভাবেই বক্সে পরিণত হতে চলেছে তখন আপনি বক্সিংয়ের পারফরম্যান্স হিট এড়াতে চান না।

মিকারেলের নীচে দেওয়া পরামর্শ:

এটা কর

using System.Collections.Generic;

var employeeCount = 5;
var list = new List<int>(10);

এটা না

using System.Collections;

Int32 employeeCount = 5;
var list = new ArrayList(10);

হালনাগাদ

এই উত্তরটি মূলত ইন্ট 32, বুল ইত্যাদি বক্সিংয়ের কারণ হিসাবে প্রস্তাব করেছিল, যখন বাস্তবে তারা মান প্রকারের জন্য সহজ উপকরণ হয়। এটি হ'ল নেটটিতে বুল, ইন্ট 32, স্ট্রিং এবং সি # এর মতো প্রকার রয়েছে যা কোনও কার্যকরী পার্থক্য ছাড়াই তাদের বুল, ইনট, স্ট্রিং এনে দেয়।


4
আপনি আমাকে শিখিয়েছিলেন যে একশত প্রোগ্রামার এবং আইটি-পেশাদাররা বছরগুলিতে কী ব্যাখ্যা করতে পারে না, তবে কী এড়ানো উচিত তার পরিবর্তে আপনার কী করা উচিত তা বলার জন্য এটি পরিবর্তন করুন , কারণ এটি অনুসরণ করা কিছুটা কঠিন হয়ে পড়েছিল .. মূল নিয়মগুলি প্রায়শই যায় না 1 । আপনি এটি করবেন না, পরিবর্তে এটি করুন
মিকেল পূসারি

2
এই উত্তরটি উত্তর হিসাবে একশবার চিহ্নিত করা উচিত!
পাইউয়ান

3
সি # তে "ইনট" নেই, সেখানে ইনট এবং ইন্ট 32 রয়েছে। আমি বিশ্বাস করি যে আপনি উল্লেখ করে ভুল করছেন যে একটি মান মান এবং অন্যটি হ'ল মানের ধরণটি মোড়ানো একটি রেফারেন্স টাইপ। আমি ভুল না হলে জাভাতে এটি সত্য, তবে সি # নয়। সি # তে যেগুলি আইডিইতে নীল দেখায় তারা তাদের কাঠামোর সংজ্ঞায়নের জন্য ব্যক্তিগত নাম। সুতরাং: ইন্টি = ইনট 32, বুল = বুলিয়ান, স্ট্রিং = স্ট্রিং। বুলিয়ানের উপরে বুল ব্যবহার করার কারণটি এটি এমএসডিএন ডিজাইনের গাইডলাইন এবং কনভেনশনগুলিতে যেমন প্রস্তাবিত হয়। অন্যথায় আমি এই উত্তরটি ভালবাসি। তবে আপনি আমাকে ভুল প্রমাণ না করা বা আপনার উত্তরে ঠিক না করা পর্যন্ত আমি ভোটটি নামিয়ে দেব will
হেরিবার্তো লুগো

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

2
@ হেরিবার্টোলুগো সঠিক, "আপনার মূল্য ধরণের ধরণের কথা বলার পরিবর্তে আপনাকে বুল হিসাবে ঘোষণা করা উচিত" লাইনটি ভুল হয়েছে। যেমন ওপি নির্দেশ করে আপনি আপনার বুল (বা বুলিয়ান, বা অন্য কোনও মান ধরণের) অবজেক্ট হিসাবে ঘোষণা করা এড়ানো উচিত। বুল / বুলিয়ান, ইন্টি / ইন্ট 32, সি # এবং .NET: ডকস.মাইক্রোসফটকম
STW

21

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

জেনেরিক সংগ্রহগুলি এখন ব্যবহার করে, এটি বেশ দূরে চলে যায়। আপনি যদি একটি তৈরি করেন List<int>, কোনও বক্সিং সম্পন্ন হয় না - List<int>সরাসরি সংখ্যাগুলি ধরে রাখতে পারে।


যৌগিক স্ট্রিং ফর্ম্যাটিংয়ের মতো জিনিসগুলির জন্য আপনার এখনও বক্সিং দরকার। জেনারিকগুলি ব্যবহার করার সময় আপনি এটি প্রায়শই দেখতে পাবেন না তবে এটি অবশ্যই এখনও রয়েছে।
জেরেমি এস

1
সত্য - এটি ADO.NET- এও সর্বদা প্রদর্শিত হয় - স্কেল প্যারামিটার মানগুলি হ'ল আসল ডেটা টাইপ কী তা বিবেচনা করে না
রায়

11

বক্সিং এবং আনবক্সিং বিশেষত মান-ধরণের অবজেক্টগুলিকে রেফারেন্স-টাইপ হিসাবে ব্যবহার করার জন্য ব্যবহৃত হয়; তাদের প্রকৃত মানটিকে পরিচালিত হিপগুলিতে স্থানান্তরিত করা এবং রেফারেন্সের মাধ্যমে তাদের মানটি অ্যাক্সেস করা।

বক্সিং এবং আনবক্সিং ছাড়াই আপনি কখনই রেফারেন্সের মাধ্যমে মান-প্রকারগুলি পাস করতে পারবেন না; এবং এর অর্থ আপনি বস্তুর উদাহরণ হিসাবে মান-প্রকারগুলি পাস করতে পারেন নি।


এখনও চমৎকার উত্তর প্রায় 10 বছর স্যার +1 টি পরে
SNR

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

8

আমার শেষ কিছুটি আনবক্স করতে হয়েছিল এমন কোনও কোড লিখতে গিয়ে যেটি একটি ডাটাবেস থেকে কিছু তথ্য উদ্ধার করে (আমি লিনকিউ এসকিউএল এ ব্যবহার করি না , কেবল পুরানো অ্যাডো.নেট ):

int myIntValue = (int)reader["MyIntValue"];

মূলত, আপনি জেনেরিকের আগে যদি পুরানো এপিআইগুলির সাথে কাজ করেন তবে আপনার বক্সিংয়ের মুখোমুখি হবে। তা ছাড়া, এটি তেমন সাধারণ নয়।


4

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

আমি এটি সত্য বলে মনে করি না, পরিবর্তে এটি ব্যবহার করে দেখুন:

class Program
    {
        static void Main(string[] args)
        {
            int x = 4;
            test(x);
        }

        static void test(object o)
        {
            Console.WriteLine(o.ToString());
        }
    }

এটি ঠিক চলছে, আমি বক্সিং / আনবক্সিং ব্যবহার করিনি। (সংকলক যদি না পর্দার আড়ালে তা করে?)


এর কারণ হ'ল সিস্টেম.অবজেক্ট থেকে সমস্ত কিছুই উত্তরাধিকার সূত্রে প্রাপ্ত এবং আপনি পদ্ধতিটিকে অতিরিক্ত তথ্য দিয়ে একটি অবজেক্ট দিচ্ছেন, তাই মূলত আপনি পরীক্ষার পদ্ধতিটি যা প্রত্যাশা করছেন এবং যা কিছু প্রত্যাশা করে তা কল করে যাচ্ছেন কারণ এটি বিশেষত কিছু প্রত্যাশা করে না।
নেটের মধ্যে অনেকগুলি

1

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


0

যখন কোনও পদ্ধতি কেবলমাত্র প্যারামিটার হিসাবে একটি রেফারেন্স টাইপ নেয় (সীমাবদ্ধতার মাধ্যমে শ্রেণি হতে বাধ্য জেনেরিক পদ্ধতিটি বলুন new), আপনি এটিতে কোনও রেফারেন্স টাইপ পাস করতে সক্ষম হবেন না এবং এটি বাক্সে রাখতে পারবেন না।

এটাও কোনো পদ্ধতি যে নিতে জন্য সত্য objectএকটি প্যারামিটার হিসাবে - এই হবে আছে একটি রেফারেন্স টাইপ করতে হবে।


0

সাধারণভাবে, আপনি সাধারণত আপনার মূল্য ধরণের বক্সিং এড়াতে চাইবেন।

যাইহোক, বিরল ঘটনাগুলি যেখানে এটি দরকারী are উদাহরণস্বরূপ, আপনার যদি 1.1 কাঠামোটি লক্ষ্য করতে হয় তবে আপনার জেনেরিক সংগ্রহগুলিতে অ্যাক্সেস পাবেন না। .NET 1.1 এ সংগ্রহগুলির যে কোনও ব্যবহারের জন্য আপনার মান ধরণেরটিকে সিস্টেম হিসাবে বিবেচনা করা প্রয়োজন b অবজেক্ট, যার ফলে বক্সিং / আনবক্সিং হয়।

.NET 2.0+ এ কার্যকর হওয়ার জন্য এখনও কিছু কেস রয়েছে। যে কোনও সময় আপনি এই ধরণের সুবিধা নিতে চান যে মান ধরণের সহ সমস্ত প্রকারকে সরাসরি একটি বস্তু হিসাবে বিবেচনা করা যেতে পারে, আপনাকে বক্সিং / আনবক্সিং ব্যবহার করতে হতে পারে। এটি মাঝে মাঝে সুবিধাজনক হতে পারে, যেহেতু এটি আপনাকে কোনও সংগ্রহের মধ্যে যেকোন প্রকারের সংরক্ষণ করতে দেয় (জেনেরিক সংগ্রহের ক্ষেত্রে টিয়ের পরিবর্তে অবজেক্ট ব্যবহার করে), তবে সাধারণভাবে, আপনি এ জাতীয় সুরক্ষা হারাচ্ছেন বলে এটি এড়ানো ভাল। একটি ক্ষেত্রে যেখানে বক্সিং প্রায়শই ঘটে থাকে তা হ'ল আপনি যখন প্রতিচ্ছবিটি ব্যবহার করেন - প্রতিচ্ছবির অনেকগুলি কলকে মূল্য টাইপের সাথে কাজ করার সময় বক্সিং / আনবক্সিংয়ের প্রয়োজন হবে, কারণ টাইপটি আগে থেকেই জানা ছিল না।


0

বক্সিং হ'ল কোনও বস্তুতে অফসেটে ডেটা সহ রেফারেন্স টাইপের একটি মান রূপান্তর is

বক্সিং আসলে কি করে। এখানে কিছু উদাহরণঃ

মনো সি ++

void* mono_object_unbox (MonoObject *obj)
 {    
MONO_EXTERNAL_ONLY_GC_UNSAFE (void*, mono_object_unbox_internal (obj));
 }

#define MONO_EXTERNAL_ONLY_GC_UNSAFE(t, expr) \
    t result;       \
    MONO_ENTER_GC_UNSAFE;   \
    result = expr;      \
    MONO_EXIT_GC_UNSAFE;    \
    return result;

static inline gpointer
mono_object_get_data (MonoObject *o)
{
    return (guint8*)o + MONO_ABI_SIZEOF (MonoObject);
}

#define MONO_ABI_SIZEOF(type) (MONO_STRUCT_SIZE (type))
#define MONO_STRUCT_SIZE(struct) MONO_SIZEOF_ ## struct
#define MONO_SIZEOF_MonoObject (2 * MONO_SIZEOF_gpointer)

typedef struct {
    MonoVTable *vtable;
    MonoThreadsSync *synchronisation;
} MonoObject;

মনোতে আনবক্সিং হ'ল অবজেক্টের 2 জিপয়েন্টার (যেমন 16 বাইট) অফসেটে পয়েন্টার ingালাইয়ের প্রক্রিয়া। ক gpointerহয় ক void*। সংজ্ঞাটি দেখার সময় এটি অর্থবোধক MonoObjectহিসাবে এটি স্পষ্টভাবে ডেটার জন্য কেবল একটি শিরোনাম।

সি ++

সি ++ তে একটি মান বাক্স করতে আপনি যেমন কিছু করতে পারেন:

#include <iostream>
#define Object void*

template<class T> Object box(T j){
  return new T(j);
}

template<class T> T unbox(Object j){
  T temp = *(T*)j;
  delete j;
  return temp;
}

int main() {
  int j=2;
  Object o = box(j);
  int k = unbox<int>(o);
  std::cout << k;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.