কাঠামো কখন ব্যবহার করবেন?


1390

আপনি কখন সি # তে ক্লাস না করে কাঠামো ব্যবহার করবেন? আমার ধারণাগত মডেলটি হ'ল স্ট্রাক্টগুলি এমন সময়ে ব্যবহৃত হয় যখন আইটেমটি কেবলমাত্র মূল্য ধরণের সংগ্রহ । যৌক্তিকভাবে তাদের সমস্তকে একত্রিত করার জন্য একটি উপায় hes

আমি এই নিয়মগুলি এখানে এসেছি :

  • কাঠামোর একটি একক মান উপস্থাপন করা উচিত।
  • একটি স্ট্রাক্টে 16 বাইটের চেয়ে কম মেমরির পদচিহ্ন থাকতে হবে।
  • কোনও কাঠামো তৈরির পরে পরিবর্তন করা উচিত নয়।

এই নিয়মগুলি কি কাজ করে? কাঠামো অর্থহীন অর্থ কী?


247
System.Drawing.Rectangleএই তিনটি নিয়ম লঙ্ঘন করে।
ক্রিসডাব্লু

4
সি # তে বেশ কয়েকটি বাণিজ্যিক গেমস লেখা আছে, মূল কথাটি হ'ল এগুলি অপ্টিমাইজড কোডের জন্য ব্যবহৃত হয়
ব্ল্যাকটাইজারএক্স

25
কাঠামোগুলি যখন আপনার একসাথে গ্রুপ করতে চান এমন মান-প্রকারের ছোট সংগ্রহ থাকে তখন কাঠামোগুলি আরও ভাল কার্য সম্পাদন করে provide গেম প্রোগ্রামিংয়ে সর্বদা এটি ঘটে থাকে, উদাহরণস্বরূপ, 3 ডি মডেলের একটি ভার্টেক্সের অবস্থান, টেক্সচারের সমন্বয় এবং একটি স্বাভাবিক থাকবে, এটি সাধারণত অপরিবর্তনীয় হতে চলেছে। একটি একক মডেলের কয়েক হাজার शिरোখণ্ড থাকতে পারে, বা এটিতে এক ডজন থাকতে পারে তবে স্ট্রাক্টগুলি ব্যবহারের দৃশ্যে সামগ্রিকভাবে কম ওভারহেড সরবরাহ করে। আমি নিজের ইঞ্জিন ডিজাইনের মাধ্যমে এটি যাচাই করেছি।
ক্রিস ডি

6
@ এরিকফোর্ডস: আমার মনে হয় এটিকে সাধারণত সবচেয়ে বড় বিসিএল "

4
@ ক্রিসডব্লু আমি দেখছি, কিন্তু সেই মানগুলি কি একটি আয়তক্ষেত্রকে প্রতিনিধিত্ব করে না, যা একটি "একক" মান? ভেক্টর 3 ডি বা রঙের মতো, সেগুলি ভিতরেও বেশ কয়েকটি মান, তবে আমি মনে করি তারা একক মানকে উপস্থাপন করে?
মারসন মাও

উত্তর:


604

ওপি দ্বারা সূচিত উত্সটির কিছুটা বিশ্বাসযোগ্যতা রয়েছে ... তবে মাইক্রোসফ্টের কী - স্ট্রাক্ট ব্যবহারের বিষয়ে অবস্থান কী? আমি মাইক্রোসফ্টের কাছ থেকে কিছু অতিরিক্ত শিখতে চেয়েছি এবং আমি যা পেয়েছি তা এখানেই রয়েছে:

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

ধরণের নিম্নলিখিত বৈশিষ্ট্যগুলির মধ্যে না থাকলে কোনও কাঠামো সংজ্ঞায়িত করবেন না:

  1. এটি যৌক্তিকভাবে একক মানকে উপস্থাপিত করে, আদিম ধরণের (পূর্ণসংখ্যা, ডাবল এবং আরও কিছু) অনুরূপ।
  2. এটির একটি আকারের আকার 16 বাইটের চেয়ে ছোট।
  3. এটি অপরিবর্তনীয়।
  4. এটি ঘন ঘন বক্স করতে হবে না।

মাইক্রোসফ্ট নিয়মিতভাবে এই নিয়মগুলি লঙ্ঘন করে

ঠিক আছে, যাই হোক না কেন # 2 এবং # 3। আমাদের প্রিয় অভিধানটিতে দুটি অভ্যন্তরীণ স্ট্রাক্ট রয়েছে:

[StructLayout(LayoutKind.Sequential)]  // default for structs
private struct Entry  //<Tkey, TValue>
{
    //  View code at *Reference Source
}

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator : 
    IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, 
    IDictionaryEnumerator, IEnumerator
{
    //  View code at *Reference Source
}

* রেফারেন্স উত্স

'জনিক্যান্টকোড ডট কম' উত্সটি 4 টির মধ্যে 3 পেয়েছে - যেহেতু # 4 সম্ভবত এটি কোনও সমস্যা হবে না quite যদি আপনি নিজেকে স্ট্রাক্ট বক্সিং মনে করেন তবে আপনার আর্কিটেকচারটি পুনর্বিবেচনা করুন।

মাইক্রোসফ্ট কেন এই স্ট্রাক্ট ব্যবহার করবে তা দেখুন:

  1. প্রতিটি কাঠামো, Entryএবং Enumerator, একক মান উপস্থাপন করে।
  2. দ্রুততা
  3. Entryঅভিধান ক্লাসের বাইরে কখনও প্যারামিটার হিসাবে পাস হয় না। আরও তদন্তে দেখা যায় যে আইনুনামেবলের বাস্তবায়ন সন্তুষ্ট করার জন্য, অভিধানটি সেই কাঠামোটি ব্যবহার করে Enumeratorযা এটি প্রতিবার কোনও গণকের অনুরোধের সময় অনুলিপি করে ... তা বোঝায়।
  4. অভিধান ক্লাসে অভ্যন্তরীণ। Enumeratorঅভিধানটি গণনাযোগ্য, কারণ এটি আইকনমেন্টার ইন্টারফেস বাস্তবায়নের সমান অ্যাক্সেসিবিলিটি থাকতে পারে - যেমন আইইনুমেরেটর প্রাপ্তি।

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

আমরা এখানে যা দেখছি না তা হ'ল স্ট্রাক্টগুলি অপরিবর্তনীয় রাখার জন্য প্রয়োজনীয়তার প্রয়াস বা প্রমাণ যা কেবলমাত্র 16 বাইট বা তার চেয়ে কম আকারের উদাহরণ বজায় রাখতে হবে:

  1. উপরের স্ট্রাইকগুলির কোনও কিছুই ঘোষণা করা হয়নি readonly- স্থাবর নয়
  2. এই কাঠামোর আকার 16 বাইটের বেশি হতে পারে
  3. Entryএকটি অনির্ধারিত জীবনকাল আছে (থেকে Add(), এর Remove(), Clear()অথবা আবর্জনা সংগ্রহ);

এবং ... ৪. উভয় স্ট্রাক্টই TKey এবং TValue স্টোর করে, যা আমরা সবাই জানি রেফারেন্স টাইপ হওয়ার পক্ষে যথেষ্ট সক্ষম (যুক্ত বোনাস তথ্য)

তবুও, হ্যাশ কীগুলি সত্ত্বেও, অভিধানগুলি অংশে দ্রুত are এখানে আমার কাছে একটি Dictionary<int, int>ক্রমবর্ধমান কীগুলির সাথে 300,000 এলোমেলো পূর্ণসংখ্যার সঞ্চয় রয়েছে।

ক্ষমতা: 312874
মেমসাইজ: 2660827 বাইটস
সম্পূর্ণ পুনরায় আকার: 5 এমএস পূরণের
মোট সময়: 889ms

ক্ষমতা : অভ্যন্তরীণ অ্যারেটিকে পুনরায় আকার দেওয়ার আগে প্রয়োজনীয় উপাদানের সংখ্যা।

মেমসাইজ : অভিধানকে মেমোরিস্ট্রিমে সিরিয়ালাইজ করে এবং একটি বাইট দৈর্ঘ্য (আমাদের উদ্দেশ্যগুলির জন্য যথেষ্ট সঠিক) পেয়ে নির্ধারিত।

সম্পূর্ণ আকার পরিবর্তন: 150862 উপাদান থেকে 312874 উপাদানগুলিতে অভ্যন্তরীণ অ্যারেটিকে পুনরায় আকার দিতে সময় লাগে। যখন আপনি দেখেন যে প্রতিটি উপাদান ক্রমানুসারে অনুলিপি করা হয় Array.CopyTo(), এটি খুব জঞ্জাল নয়।

ভরাট করার মোট সময় : লগিংয়ের কারণে স্বীকৃতভাবে স্কিউড এবং উত্সটিতে OnResizeআমি একটি ইভেন্ট যুক্ত করেছি; তবে, অপারেশন চলাকালীন 15 বার পুনরায় আকার দেওয়ার সময় 300k পূর্ণসংখ্যা পূরণ করতে এখনও চিত্তাকর্ষক। মাত্র কৌতূহলের বাইরে, যদি আমি ইতিমধ্যে ক্ষমতাটি জানতাম তবে মোট পূরণের সময়টি কত হবে? 13ms

সুতরাং, এখন, যদি Entryএকটি ক্লাস হত? এই সময় বা মেট্রিকস কি সত্যিই অনেক আলাদা হবে?

ক্ষমতা: 312874
মেমসাইজ: 2660827 বাইট
সম্পূর্ণ পুনরায় আকার: 26 মিম পূরণের
মোট সময়: 964ms

স্পষ্টতই, বড় পার্থক্যটি আকার পরিবর্তন করতে হয়। সক্ষমতা দিয়ে অভিধান শুরু করা থাকলে কোনও পার্থক্য? ... 12 মিমি নিয়ে উদ্বিগ্ন হওয়ার জন্য যথেষ্ট নয় ।

যা ঘটে তা হ'ল কারণ Entryএটি একটি কাঠামো, এটির জন্য কোনও রেফারেন্স টাইপের মতো আরম্ভের প্রয়োজন হয় না। এটি সৌন্দর্য ধরণ এবং মান ধরণের নিষ্ক্রিয় উভয়ই। Entryএকটি রেফারেন্স টাইপ হিসাবে ব্যবহার করতে , আমাকে নিম্নলিখিত কোডটি প্রবেশ করানো হয়েছিল:

/*
 *  Added to satisfy initialization of entry elements --
 *  this is where the extra time is spent resizing the Entry array
 * **/
for (int i = 0 ; i < prime ; i++)
{
    destinationArray[i] = new Entry( );
}
/*  *********************************************** */  

Entryরেফারেন্স টাইপ হিসাবে আমাকে প্রতিটি অ্যারের উপাদানটি সূচনা করার কারণটি এমএসডিএন: স্ট্রাকচার ডিজাইনে পাওয়া যাবে । সংক্ষেপে:

কোনও কাঠামোর জন্য কোনও ডিফল্ট কনস্ট্রাক্টর সরবরাহ করবেন না।

যদি কোনও কাঠামো একটি ডিফল্ট কনস্ট্রাক্টরকে সংজ্ঞায়িত করে, যখন কাঠামোর অ্যারে তৈরি করা হয়, সাধারণ ভাষা রানটাইম স্বয়ংক্রিয়ভাবে প্রতিটি অ্যারের উপাদানটিতে ডিফল্ট কনস্ট্রাক্টরকে কার্যকর করে।

কিছু সংকলক যেমন সি # সংকলক স্ট্রাকচারকে ডিফল্ট কনস্ট্রাক্টর থাকতে দেয় না।

এটি আসলে বেশ সহজ এবং আমরা অসিমভের রোবোটিক্সের তিনটি আইন থেকে willণ নেব :

  1. কাঠামো অবশ্যই ব্যবহারের জন্য নিরাপদ থাকতে হবে
  2. স্ট্রাক্ট অবশ্যই অবশ্যই তার কার্য সম্পাদন করবে, যদি না এটি # 1 বিধি লঙ্ঘন করে
  3. কাঠামোটি ব্যবহারের সময় অবশ্যই অক্ষত থাকতে হবে যতক্ষণ না এর ধ্বংসের প্রয়োজন হয় # 1 বিধি পূরণ করার জন্য

... আমরা এ থেকে কী নেব : সংক্ষেপে, মান ধরণের ব্যবহারের সাথে দায়বদ্ধ। এগুলি দ্রুত এবং দক্ষ, তবে সঠিকভাবে রক্ষণাবেক্ষণ না করা হলে (যেমন অনিচ্ছাকৃত অনুলিপিগুলি) অনেকগুলি অপ্রত্যাশিত আচরণের সক্ষমতা রয়েছে।


8
মাইক্রোসফ্টের বিধি হিসাবে, অপরিবর্তনীয়তা সম্পর্কে নিয়মটি এমনভাবে মূল্য প্রকারের ব্যবহারকে নিরুৎসাহিত করার জন্য ডিজাইন করা হয়েছে যাতে তাদের আচরণটি রেফারেন্স ধরণেরগুলির চেয়ে পৃথক হয়ে যায়, তবুও এই অংশটি যে পিসওয়াস-মিউটਟੇਬਲ মান শব্দার্থিকগুলি কার্যকর হতে পারে । যদি কোনও ধরণটি টুকরোপে পরিবর্তিত হয় তবে এতে কাজ করা সহজ হয় এবং যদি ধরণের স্টোরেজ অবস্থানগুলি একে অপরের থেকে যুক্তিযুক্তভাবে আলাদা করা যায় তবে টাইপটি "পরিবর্তনীয়" কাঠামো হওয়া উচিত।
সুপারক্যাট


2
মাইক্রোসফ্টের অনেক ধরণের এই নিয়মগুলিকে লঙ্ঘন করে এমন ঘটনা এই ধরণের সমস্যাগুলির প্রতিনিধিত্ব করে না, বরং নির্দেশ করে যে সমস্ত বিধিগুলি কাঠামোর ধরণের ক্ষেত্রে প্রযোজ্য নয়। যদি কোনও কাঠামো কোনও একক সত্তাকে [যেমন Decimalবা তার সাথে DateTime] প্রতিনিধিত্ব করে, তবে যদি এটি অন্য তিনটি বিধি মেনে না চলে, তবে এটি একটি শ্রেণি দ্বারা প্রতিস্থাপন করা উচিত। যদি কোনও কাঠামোতে ভেরিয়েবলের একটি নির্দিষ্ট সংকলন থাকে, যার মধ্যে প্রতিটি তার ধরণের জন্য বৈধ হতে পারে এমন কোনও মান ধরে রাখতে পারে [উদাহরণস্বরূপ Rectangle], তবে এটি বিভিন্ন বিধি দ্বারা মেনে চলতে হবে , যার কয়েকটি "একক মান" স্ট্রকের বিপরীতে রয়েছে ।
সুপারক্যাট

4
@ আইবিস্ট্র্যাক্ট: কিছু লোক Dictionaryএন্ট্রি প্রকারটিকে কেবলমাত্র একটি অভ্যন্তরীণ প্রকারের ভিত্তিতে ন্যায্যতা জানায় , শব্দার্থতত্ত্ব বা অন্য কোনও অজুহাতে পারফরম্যান্সকে আরও গুরুত্বপূর্ণ হিসাবে বিবেচনা করা হত। আমার বক্তব্যটি হ'ল কোনও প্রকারের মতো Rectangleবিষয়বস্তু পৃথকভাবে সম্পাদনযোগ্য ক্ষেত্র হিসাবে প্রকাশ করা উচিত "কারণ" পারফরম্যান্সের ফলে প্রাপ্ত ফলাফলগুলির অপূর্ণতা ছাড়িয়ে যায় তবে এই শব্দটি সিন্থেটিকভাবে স্বতন্ত্র মানগুলির একটি নির্দিষ্ট সেটকে উপস্থাপন করে এবং তাই পরিবর্তনীয় কাঠামো উভয়ই আরও পারফরম্যান্ট এবং শব্দার্থগতভাবে উচ্চতর
সুপারক্যাট

2
@ সুপের্যাট: আমি একমত ... এবং আমার উত্তরের পুরো বক্তব্যটি ছিল 'গাইডলাইনস' বেশ দুর্বল এবং আচরণগুলি সম্পর্কে সম্পূর্ণ জ্ঞান এবং বোঝার সাথে স্ট্রাক্টগুলি ব্যবহার করা উচিত। : এখানে চপল struct হয় আমার উত্তর দেখার stackoverflow.com/questions/8108920/...
IAbstract

154

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


1
এটি কেবল একটি "ক্যাভিয়েট"। (Guid)nullঅন্যান্য বিষয়গুলির মধ্যে ( যেমন একটি রেফারেন্স-ধরণের কাছে নাল দেওয়া ঠিক হবে) যেমন মান-প্রকার এবং কেসগুলির "উত্তোলন" বিবেচনা করা উচিত ।

1
সি / সি ++ এর চেয়ে বেশি ব্যয়বহুল? সি ++ এ প্রস্তাবিত উপায় হ'ল বস্তুগুলি মান দ্বারা পাস করা হয়
অয়ন টোডেরেল

@ আইওনটডিরেল কি পারফরম্যান্সের পরিবর্তে মেমরির সুরক্ষার কারণে নয়? এটি সর্বদা একটি বাণিজ্য-বন্ধ, তবে স্ট্যাকের মাধ্যমে 32 বি পাস করা সর্বদা (টিএম) রেজিস্টার দ্বারা 4 বি রেফারেন্স পাস করার চেয়ে ধীর হতে চলেছে। তবে , আরও লক্ষ করুন যে "মান / রেফারেন্স" এর ব্যবহার সি # এবং সি ++-তে কিছুটা আলাদা - মূলত রেফারেন্সের কোনও রেফারেন্স নয়, রেফারেন্সের মানটি দিয়ে যাচ্ছেন। এটি শব্দার্থবিজ্ঞানের মান নয় , তবে এটি প্রযুক্তিগতভাবে "পাস-বাই-মান"।
লুয়ান

@ লুয়ান কপি করা ব্যয়ের একটি মাত্র দিক। পয়েন্টার / রেফারেন্সের কারণে অতিরিক্ত ইন্ডিরিয়ারেশনও অ্যাক্সেসের জন্য ব্যয় করে। কিছু ক্ষেত্রে কাঠামো এমনকি সরানো যায় এবং এইভাবে অনুলিপি করার প্রয়োজন হয় না।
ওনুর

@ অনুর এটি আকর্ষণীয় আপনি অনুলিপি না করে কীভাবে "সরান"? আমি ভেবেছিলাম asm "মুভ" নির্দেশনা আসলে "সরানো" হয় না। এটি অনুলিপি।
উইঙ্গার সেন্ডন

148

আমি মূল পোস্টে দেওয়া বিধিগুলির সাথে একমত নই। আমার নিয়মগুলি এখানে:

1) অ্যারেতে সংরক্ষণ করার সময় আপনি কার্য সম্পাদনের জন্য স্ট্রাক্ট ব্যবহার করেন। ( উত্তরটি কবে স্ট্রাইক হয় তাও দেখুন ? )

2) আপনার কোডগুলি সি / সি ++ থেকে / থেকে স্ট্রাকচার্ড ডেটা পাস করার প্রয়োজন need

3) আপনার প্রয়োজন না হলে স্ট্রাইক ব্যবহার করবেন না:

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

4
+1 হ্যাঁ, আমি # 1 সম্পূর্ণরূপে একমত ( ইমেজ ইত্যাদির মতো জিনিসগুলির সাথে কাজ করার ক্ষেত্রে এটি একটি বিশাল সুবিধা) এবং এটি "সাধারণ বিষয়গুলি" থেকে পৃথক এবং এটি বিদ্যমান জ্ঞান ব্যতীত এটি জানার উপায় রয়েছে বা নিজেই টাইপ পরীক্ষা করা। এছাড়াও, আপনি কোনও কাঠামোর ধরণের কাছে নাল মান দিতে পারবেন না :-) এটি আসলে এমন একটি ক্ষেত্রে যেখানে আমি প্রায় ইচ্ছে করে নন-কোর মান-প্রকারের জন্য কিছু 'হাঙ্গেরিয়ান' বা ভেরিয়েবল ডিক্লেয়ারেশন সাইটে একটি বাধ্যতামূলক 'স্ট্রাক্ট' কীওয়ার্ড ছিল ।

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

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

# 1 দিয়ে স্পট করুন। স্ট্রাক্টগুলি পূর্ণ একটি তালিকা অবজেক্ট রেফারেন্স পূর্ণ তালিকা (ডান আকারের কাঠামোর জন্য) এর চেয়ে L1 / L2 ক্যাশে অনেক বেশি প্রাসঙ্গিক ডেটা চেপে ফেলতে পারে।
ম্যাট স্টিফেনসন

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

87

রেফারেন্স শব্দার্থবিজ্ঞানের বিপরীতে যখন মান শব্দার্থক চান তখন একটি স্ট্রাক ব্যবহার করুন।

সম্পাদন করা

ভাবেন না কেন লোকেরা এটিকে নিম্নচাপ দিচ্ছে তবে এটি একটি বৈধ পয়েন্ট এবং অপারেটর তার প্রশ্নটি পরিষ্কার করার আগে তৈরি করা হয়েছিল এবং এটি স্ট্রাক্টের সবচেয়ে মৌলিক কারণ reason

আপনার যদি রেফারেন্স শব্দার্থবিজ্ঞানের প্রয়োজন হয় তবে আপনার স্ট্রাক্ট নয়, ক্লাসের প্রয়োজন।


13
এটা সবাই জানে. দেখে মনে হচ্ছে তিনি "স্ট্রাক্ট একটি মান ধরণের" উত্তর চেয়ে বেশি খুঁজছেন।
TheSmurf

21
এটি সবচেয়ে বেসিক কেস এবং যে কেউ এই পোস্টটি পড়েন এবং জানেন না তাদের জন্য বলা উচিত।
জোশবার্ক

3
এই উত্তরটি সত্য নয় বলে নয়; এটা অবশ্যই হয়। এটা আসলে কথা নয়।
TheSmurf

55
@ জোশ: যে কেউ ইতিমধ্যে এটি জানে না তাদের পক্ষে কেবল এটি একটি অপর্যাপ্ত উত্তর, যেহেতু সম্ভবত তারা সম্ভবত এটির অর্থ কী তা জানেন না।
TheSmurf

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

59

"এটি একটি মান" উত্তর ছাড়াও, স্ট্র্ট ব্যবহারের জন্য একটি নির্দিষ্ট দৃশ্যটি যখন আপনি জানেন যে আপনার কাছে এমন একটি ডেটা সেট রয়েছে যা জঞ্জাল সংগ্রহের সমস্যার কারণ হয়ে দাঁড়িয়েছে এবং আপনার প্রচুর অবজেক্ট রয়েছে। উদাহরণস্বরূপ, ব্যক্তির উদাহরণগুলির একটি বড় তালিকা / অ্যারে। এখানকার প্রাকৃতিক রূপকটি একটি শ্রেণিবদ্ধ, তবে আপনার যদি দীর্ঘসংখ্যক দীর্ঘকালীন ব্যক্তির উদাহরণ থাকে তবে এগুলি জিএন -২ আটকে থাকতে পারে এবং জিসি স্টলের কারণ হতে পারে। তাহলে দৃশ্যকল্প পরোয়ানা এটা এক সম্ভাব্য এখানে পদ্ধতির একটি অ্যারের পারসন এর (না তালিকা) ব্যবহার করা structs মধ্যে , অর্থাত্ Person[]। এখন, জেন -২ এ মিলিয়ন মিলিয়ন অবজেক্ট থাকার পরিবর্তে আপনার এলওএইচ-এর একক অংশ রয়েছে (আমি এখানে কোনও স্ট্রিং ইত্যাদি ধরে নিচ্ছি না - অর্থাত্ কোনও উল্লেখ ছাড়াই একটি খাঁটি মান)। এটিতে খুব কম জিসির প্রভাব পড়ে।

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

int index = ...
int id = peopleArray[index].Id;

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

void Foo(ref Person person) {...}
...
Foo(ref peopleArray[index]);

আবার, এটি স্থানস্থ - আমরা মানটি অনুলিপি করিনি।

খুব নির্দিষ্ট পরিস্থিতিতে, এই কৌশলটি খুব সফল হতে পারে; যাইহোক, এটি একটি মোটামুটি উন্নত scernario যা আপনি কী করছেন এবং কেন জানেন তা যদি কেবল তখনই চেষ্টা করা উচিত। ডিফল্ট এখানে একটি বর্গ হবে।


+1 আকর্ষণীয় উত্তর। আপনি কি এই জাতীয় পদ্ধতির ব্যবহার সম্পর্কে কোন বাস্তব বিশ্বের উপাখ্যান ভাগ করতে ইচ্ছুক?
জর্ডো

@ জোর্ডাও মোবাইলে প্রবেশ করুন তবে গুগল অনুসন্ধান করুন: + গ্রেল + "জিসি দ্বারা আক্রমণ"
মার্ক গ্র্যাভেল

1
অনেক ধন্যবাদ. আমি এটি এখানে খুঁজে পেয়েছি ।
জর্দো

2
@ মার্কগ্রাভেল আপনি কেন উল্লেখ করেছেন: একটি অ্যারে ব্যবহার করবেন (তালিকা নয়) ? Listআমি বিশ্বাস করি, একটি Arrayপিছনের পর্দা ব্যবহার করে । না?
রয়ী নামির

4
@ রোয়নিমির আমিও এ সম্পর্কে আগ্রহী ছিলাম, তবে আমি বিশ্বাস করি যে উত্তরটি মার্কের উত্তরের দ্বিতীয় অনুচ্ছেদে রয়েছে। "তবে এটিকে সরাসরি অ্যারেতে অ্যাক্সেস করা কাঠামো অনুলিপি করে না - এটি স্থানস্থ (একটি তালিকা সূচকের বিপরীতে, যা অনুলিপি করে)"।
ব্যবহারকারী 1323245

40

থেকে C # এর ভাষা স্পেসিফিকেশন :

1.7 স্ট্রাক্টস

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

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

class Point
{
   public int x, y;

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

class Test
{
   static void Main() {
      Point[] points = new Point[100];
      for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
   }
}

বিকল্প একটি পয়েন্ট একটি কাঠামো করা হয়।

struct Point
{
   public int x, y;

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

এখন কেবলমাত্র একটি অবজেক্ট ইনস্ট্যান্ট করা আছে the অ্যারের জন্য একটি — এবং পয়েন্ট দৃষ্টান্তগুলি অ্যারে-তে লাইনে সংরক্ষণ করা হয়।

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

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

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

যদি পয়েন্টটি একটি শ্রেণি হয় তবে আউটপুট 20 হয় কারণ a এবং b একই বস্তুর রেফারেন্স করে। যদি পয়েন্টটি স্ট্রাক্ট হয় তবে আউটপুট 10 হবে কারণ a to b এর অ্যাসাইনমেন্টটি মানটির একটি অনুলিপি তৈরি করে এবং এই অনুলিপিটি পরবর্তী অ্যাসাইনমেন্ট দ্বারা কুড়ালটিতে প্রভাবিত হয় না

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


4
যদিও স্ট্রাক্টের উল্লেখগুলি স্থির করা যায় না এটি কখনও কখনও সীমাবদ্ধতা হয় তবে এটি খুব দরকারী বৈশিষ্ট্যযুক্ত। । নেট এর অন্যতম প্রধান দুর্বলতা হ'ল চিরকালের জন্য সেই বস্তুর নিয়ন্ত্রণ না হারিয়ে কোনও বাহ্যিক কোডের পরিবর্তিত কোনও পরিবর্তনের কোনও রেফারেন্সের বাইরে যাওয়ার উপায় নেই। বিপরীতে, কেউ কোনও বাহ্যিক পদ্ধতিটিকে কোনও refপরিবর্তনীয় কাঠামোর জন্য নিরাপদে দিতে পারে এবং জেনে থাকতে পারে যে বাইরের পদ্ধতিতে এটি সম্পাদন করবে তা ফিরে আসার আগেই তা সম্পন্ন হবে। এটা খুব খারাপ .net ক্ষণজীবী পরামিতি এবং ফাংশন রিটার্ন মূল্যবোধের কোনো ধারণা নেই যেহেতু ...
supercat

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

34

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


4
হ্যাঁ, তবে বড় স্ট্রাকগুলি শ্রেণীর রেফারেন্সগুলির চেয়ে বেশি ব্যয়বহুল হতে পারে (যখন পদ্ধতিগুলিতে যাওয়ার সময়)।
অ্যালেক্স

27

এখানে একটি মৌলিক নিয়ম।

  • সমস্ত সদস্য ক্ষেত্র যদি মান প্রকার হয় একটি কাঠামো তৈরি ।

  • যে কোনও একটি সদস্য ক্ষেত্র যদি রেফারেন্স টাইপ হয় তবে একটি বর্গ তৈরি করুন । এটি কারণ রেফারেন্স ধরণের ক্ষেত্রে যে কোনও উপায়ে হিপ বরাদ্দ প্রয়োজন।

Exmaples

public struct MyPoint 
{
    public int X; // Value Type
    public int Y; // Value Type
}

public class MyPointWithName 
{
    public int X; // Value Type
    public int Y; // Value Type
    public string Name; // Reference Type
}

3
অপরিবর্তনীয় রেফারেন্স ধরণের মত stringশব্দার্থগত মানের সাথে সমান, এবং কোনও ক্ষেত্রের মধ্যে একটি অপরিবর্তনীয় বস্তুর রেফারেন্স সংরক্ষণ করা হিপ বরাদ্দ প্রযোজ্য নয়। উন্মুক্ত পাবলিক ক্ষেত্রের সাথে একটি struct এবং উদ্ভাসিত পাবলিক ক্ষেত্রের সাথে একটি বর্গ বস্তুর মধ্যে পার্থক্য যে কোড ক্রম দেওয়া হয় var q=p; p.X=4; q.X=5;, p.Xযদি মান 4 থাকবে aএকটি কাঠামো ধরনের, এবং 5 যদি এটি একটি বর্গ টাইপ আছে। এক ইচ্ছাকে সুবিধামত টাইপ সদস্যদের সংশোধন করার পাবে, এক 'বর্গ' বা 'struct হয়' উপর ভিত্তি করে এক পরিবর্তন চায় কিনা নির্বাচন করা উচিত qপ্রভাবিত করার p
সুপারক্যাট

হ্যাঁ আমি সম্মতি দিচ্ছি যে রেফারেন্স ভেরিয়েবল স্ট্যাকের মধ্যে থাকবে তবে এটি যে বস্তুটিকে রেফার করবে সেটি হিপটিতে উপস্থিত থাকবে। যদিও স্ট্রাক্ট এবং ক্লাসগুলি আলাদা ভেরিয়েবলের জন্য নির্ধারিত হয়ে আলাদাভাবে আচরণ করে, তবে আমি মনে করি না এটি একটি দৃ strong় সিদ্ধান্ত নেওয়া ফ্যাক্টর।
উসমান জাফর

পরিবর্তনীয় স্ট্রাক্ট এবং পরিবর্তনীয় শ্রেণি সম্পূর্ণ আলাদাভাবে আচরণ করে; যদি একটি সঠিক হয়, অন্যটি সম্ভবত ভুল হতে পারে। আমি নিশ্চিত না যে আচরণ কীভাবে কোনও কাঠামো বা শ্রেণি ব্যবহার করবেন কিনা তা নির্ধারণের ক্ষেত্রে সিদ্ধান্তের কারণ হয়ে উঠবে না।
সুপারক্যাট

আমি বলেছিলাম এটি কোনও দৃ dec় সিদ্ধান্ত নেওয়ার কারণ নয় কারণ প্রায়শই যখন আপনি কোনও শ্রেণি বা কাঠামো তৈরি করেন আপনি কীভাবে এটি ব্যবহার করবেন তা নিশ্চিত হন না। সুতরাং আপনি কীভাবে বিষয়গুলিকে ডিজাইনের দৃষ্টিকোণ থেকে আরও বেশি বোঝার জন্য মনোনিবেশ করেন। যাইহোক আমি .NET লাইব্রেরিতে কোনও স্থানে কখনও দেখিনি যেখানে স্ট্রাক্টে একটি রেফারেন্স ভেরিয়েবল থাকে।
উসমান জাফর

1
কাঠামোর ArraySegment<T>ধরণটি একটি encapsulates T[], যা সর্বদা শ্রেণীর ধরণের। কাঠামোর ধরণ KeyValuePair<TKey,TValue>প্রায়শই জেনেরিক পরামিতি হিসাবে শ্রেণীর ধরণের সাথে ব্যবহৃত হয়।
সুপারক্যাট

19

প্রথম: ইন্টারপ দৃশ্যাবলী বা যখন আপনাকে মেমরির বিন্যাস নির্দিষ্ট করতে হবে

দ্বিতীয়: যখন তথ্য যাইহোক রেফারেন্স পয়েন্টার হিসাবে প্রায় একই আকার হয়।


17

আপনি স্ট্রাকট্রাইটআউটআউট্রিবিউট - সাধারণত পিনভোকের জন্য স্পষ্টভাবে মেমরি লেআউট নির্দিষ্ট করতে চান এমন পরিস্থিতিতে আপনার একটি "স্ট্রাক্ট" ব্যবহার করা দরকার ।

সম্পাদনা করুন: মন্তব্য নির্দেশ করে যে আপনি স্ট্রাকলআউটআউট্রিবিউটের সাথে শ্রেণি বা কাঠামো ব্যবহার করতে পারেন এবং এটি অবশ্যই সত্য। অনুশীলনে, আপনি সাধারণত একটি কাঠামো ব্যবহার করবেন - এটি স্তূপের তুলনায় স্ট্যাকের জন্য বরাদ্দ করা হয়েছে যা আপনি যদি কোনও পরিচালনা ব্যবস্থা না করে কেবল কল পদ্ধতিতে একটি যুক্তিটি পাস করছেন তবে তা বোঝা যায়।


5
স্ট্রাক্ট লেআউটআট্রিবিউট স্ট্রাক্ট বা ক্লাসে প্রয়োগ করা যেতে পারে তাই স্ট্র্টগুলি ব্যবহার করার কারণ এটি নয়।
স্টিফেন মার্টিন

আপনি যদি কেবল পরিচালনা ব্যবস্থা না করা কলটিতে যুক্তি দিয়ে যাচ্ছেন তবে কেন এটি বোধগম্য হয়?
ডেভিড ক্লেম্পফনার

16

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

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


আপনি কি সেই জন্য খুব সহজেই কোনও রেফারেন্স টাইপ ব্যবহার করতে পারবেন না?
ডেভিড ক্লেম্পফনার

15

পিনভোকের উদ্দেশ্যে রানটাইম এবং অন্যান্য অনেকে সরাসরি ব্যবহার করে এমন ভ্যালুটিটাইপগুলি ব্যতীত আপনার কেবলমাত্র 2 টি দৃশ্যে ভ্যালুটিটাইপগুলি ব্যবহার করা উচিত।

  1. যখন আপনার কপির শব্দার্থবিজ্ঞানের প্রয়োজন হবে।
  2. আপনার যখন স্বয়ংক্রিয়ভাবে আরম্ভের প্রয়োজন হয় তখন সাধারণত এই ধরণের অ্যারেতে।

# 2 মনে করা হয় অংশ নেট সংগ্রহ ক্লাসের struct হয় প্রাদুর্ভাব এর কারণ সম্পর্কে ..
IAbstract

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

13

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

ক্লাস ওভার স্ট্রাক্ট কখন ব্যবহার করবেন,

C #, structsহয় value types, ক্লাস হয় reference types। আপনি enumকীওয়ার্ড এবং কীওয়ার্ড ব্যবহার করে সি # তে মান ধরণের তৈরি করতে পারেন struct। এর value typeপরিবর্তে ব্যবহার করার reference typeফলে পরিচালিত হিপগুলিতে কম বস্তু দেখা দেবে, যার ফলে আবর্জনা সংগ্রহকারী (জিসি) এর উপর কম লোড হয়, কম ঘন ঘন জিসি চক্র হয় এবং ফলস্বরূপ আরও ভাল পারফরম্যান্স হয়। তবে, value typesতাদের ডাউনসাইডগুলিও রাখুন। একটি বড় কাছাকাছি পাস structঅবশ্যই একটি রেফারেন্স পাস করার চেয়ে ব্যয়বহুল, এটি একটি সুস্পষ্ট সমস্যা। অন্য সমস্যাটি ওভারহেডের সাথে সম্পর্কিত boxing/unboxing। আপনি কী ভাবছেন তা যদি ভাবছেন তবে boxing/unboxingএ সম্পর্কিত লিঙ্কগুলি অনুসরণ করুন boxingএবংunboxing। পারফরম্যান্স ছাড়াও, এমন সময়গুলি আসে যখন আপনার কেবল মূল্য শব্দার্থ ধারণের জন্য ধরণের প্রয়োজন হয়, যা যদি তবে প্রয়োগ করা খুব কঠিন (বা কুশ্রী) হতেreference typesআপনার যা কিছু আছে আপনার value typesকেবলমাত্র তখনই ব্যবহার করা উচিত , যখন আপনার যখন শব্দার্থবিজ্ঞানের অনুলিপি প্রয়োজন হয় বা সাধারণত arraysএই ধরণের automatic


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

... (২) যখন বিভিন্ন কারণে কোনও কাঠামো সহজভাবে ব্যবহারযোগ্য না হয় [যেমন: গাছের মতো কোনও কিছুর জন্য নেস্টেড রেফারেন্সগুলি ব্যবহার করা প্রয়োজন, বা কারণ পলিমারফিজম প্রয়োজন]। নোট করুন যে মান ধরণের ব্যবহার করার সময়, সাধারণত ক্ষেত্রগুলি সরাসরি কোনও নির্দিষ্ট কারণে অনুপস্থিত থাকায় তা প্রকাশ করা উচিত (যেখানে বেশিরভাগ শ্রেণির ক্ষেত্রের সাথে ক্ষেত্রগুলি বৈশিষ্ট্যের মধ্যে আবৃত হওয়া উচিত)। পরিবর্তনীয় মান ধরণের অনেক তথাকথিত "অশুভ" বৈশিষ্ট্যগুলিতে ক্ষেত্রগুলি অকারণে আবৃত করা থেকে উদ্ভূত হয় (উদাহরণস্বরূপ যখন কিছু সংকলক একটিকে কেবল পঠনযোগ্য কাঠামোর উপর একটি সম্পত্তি সেটারের কল করতে দেয় কারণ এটি কখনও কখনও ...
সুপারক্যাট

... সঠিক জিনিসটি করুন, সমস্ত সংকলকগুলি সরাসরি এই জাতীয় কাঠামোর ক্ষেত্রে ক্ষেত্রগুলি সেট করার প্রচেষ্টা প্রত্যাখ্যান করবে; সংকলকরা প্রত্যাখ্যান করার সর্বোত্তম উপায় readOnlyStruct.someMember = 5;হ'ল someMemberকেবলমাত্র পঠনযোগ্য সম্পত্তি তৈরি করা নয়, পরিবর্তে এটি একটি ক্ষেত্র তৈরি করা।
সুপারক্যাট

12

একটি কাঠামো একটি মান ধরণ। আপনি যদি কোনও নতুন ভেরিয়েবলের জন্য একটি কাঠামো বরাদ্দ করেন তবে নতুন ভেরিয়েবলটিতে মূলটির একটি অনুলিপি থাকবে।

public struct IntStruct {
    public int Value {get; set;}
}

স্মৃতিতে সঞ্চিত স্ট্রাক্টের 5 টি উদাহরণে নিম্নলিখিত ফলাফলগুলি অতিক্রম করা :

var struct1 = new IntStruct() { Value = 0 }; // original
var struct2 = struct1;  // A copy is made
var struct3 = struct2;  // A copy is made
var struct4 = struct3;  // A copy is made
var struct5 = struct4;  // A copy is made

// NOTE: A "copy" will occur when you pass a struct into a method parameter.
// To avoid the "copy", use the ref keyword.

// Although structs are designed to use less system resources
// than classes.  If used incorrectly, they could use significantly more.

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

public class IntClass {
    public int Value {get; set;}
}

নিম্নলিখিত ফলাফলগুলি অতিক্রম করা স্মৃতিতে শ্রেণীর অবজেক্টের কেবলমাত্র একটি উদাহরণে আসে।

var class1 = new IntClass() { Value = 0 };
var class2 = class1;  // A reference is made to class1
var class3 = class2;  // A reference is made to class1
var class4 = class3;  // A reference is made to class1
var class5 = class4;  // A reference is made to class1  

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

var struct1 = new IntStruct() { Value = 0 };
var struct2 = struct1;
struct2.Value = 1;
// At this point, a developer may be surprised when 
// struct1.Value is 0 and not 1

12

আমি সঙ্গে একটি ছোট বেঞ্চমার্ক তৈরি BenchmarkDotNet সংখ্যায় "struct হয়" উপকার ভাল করে বুঝতে জন্য। আমি স্ট্রাক (বা ক্লাস) এর অ্যারে (বা তালিকা) এর মাধ্যমে লুপিং পরীক্ষা করছি। এই অ্যারেগুলি বা তালিকাগুলি তৈরি করা বেঞ্চমার্কের আওতার বাইরে - এটি স্পষ্ট যে "শ্রেণি" আরও বেশি ভারী বেশি স্মৃতি ব্যবহার করবে এবং জিসি জড়িত থাকবে।

সুতরাং উপসংহারটি হ'ল: লিনকিউ এবং লুকানো স্ট্রাক্ট বক্সিং / আনবক্সিং সম্পর্কে সতর্ক থাকুন এবং মাইক্রোপটিমাইজেশনের জন্য স্ট্রাক্টগুলি কঠোরভাবে অ্যারেতে থাকুন।

পিএস কল স্ট্যাকের মাধ্যমে স্ট্রাক্ট / শ্রেণি পাস করার বিষয়ে আর একটি বেঞ্চমার্ক https://stackoverflow.com/a/47864451/506147

BenchmarkDotNet=v0.10.8, OS=Windows 10 Redstone 2 (10.0.15063)
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233542 Hz, Resolution=309.2584 ns, Timer=TSC
  [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
  Clr    : Clr 4.0.30319.42000, 64bit RyuJIT-v4.7.2101.1
  Core   : .NET Core 4.6.25211.01, 64bit RyuJIT


          Method |  Job | Runtime |      Mean |     Error |    StdDev |       Min |       Max |    Median | Rank |  Gen 0 | Allocated |
---------------- |----- |-------- |----------:|----------:|----------:|----------:|----------:|----------:|-----:|-------:|----------:|
   TestListClass |  Clr |     Clr |  5.599 us | 0.0408 us | 0.0382 us |  5.561 us |  5.689 us |  5.583 us |    3 |      - |       0 B |
  TestArrayClass |  Clr |     Clr |  2.024 us | 0.0102 us | 0.0096 us |  2.011 us |  2.043 us |  2.022 us |    2 |      - |       0 B |
  TestListStruct |  Clr |     Clr |  8.427 us | 0.1983 us | 0.2204 us |  8.101 us |  9.007 us |  8.374 us |    5 |      - |       0 B |
 TestArrayStruct |  Clr |     Clr |  1.539 us | 0.0295 us | 0.0276 us |  1.502 us |  1.577 us |  1.537 us |    1 |      - |       0 B |
   TestLinqClass |  Clr |     Clr | 13.117 us | 0.1007 us | 0.0892 us | 13.007 us | 13.301 us | 13.089 us |    7 | 0.0153 |      80 B |
  TestLinqStruct |  Clr |     Clr | 28.676 us | 0.1837 us | 0.1534 us | 28.441 us | 28.957 us | 28.660 us |    9 |      - |      96 B |
   TestListClass | Core |    Core |  5.747 us | 0.1147 us | 0.1275 us |  5.567 us |  5.945 us |  5.756 us |    4 |      - |       0 B |
  TestArrayClass | Core |    Core |  2.023 us | 0.0299 us | 0.0279 us |  1.990 us |  2.069 us |  2.013 us |    2 |      - |       0 B |
  TestListStruct | Core |    Core |  8.753 us | 0.1659 us | 0.1910 us |  8.498 us |  9.110 us |  8.670 us |    6 |      - |       0 B |
 TestArrayStruct | Core |    Core |  1.552 us | 0.0307 us | 0.0377 us |  1.496 us |  1.618 us |  1.552 us |    1 |      - |       0 B |
   TestLinqClass | Core |    Core | 14.286 us | 0.2430 us | 0.2273 us | 13.956 us | 14.678 us | 14.313 us |    8 | 0.0153 |      72 B |
  TestLinqStruct | Core |    Core | 30.121 us | 0.5941 us | 0.5835 us | 28.928 us | 30.909 us | 30.153 us |   10 |      - |      88 B |

কোড:

[RankColumn, MinColumn, MaxColumn, StdDevColumn, MedianColumn]
    [ClrJob, CoreJob]
    [HtmlExporter, MarkdownExporter]
    [MemoryDiagnoser]
    public class BenchmarkRef
    {
        public class C1
        {
            public string Text1;
            public string Text2;
            public string Text3;
        }

        public struct S1
        {
            public string Text1;
            public string Text2;
            public string Text3;
        }

        List<C1> testListClass = new List<C1>();
        List<S1> testListStruct = new List<S1>();
        C1[] testArrayClass;
        S1[] testArrayStruct;
        public BenchmarkRef()
        {
            for(int i=0;i<1000;i++)
            {
                testListClass.Add(new C1  { Text1= i.ToString(), Text2=null, Text3= i.ToString() });
                testListStruct.Add(new S1 { Text1 = i.ToString(), Text2 = null, Text3 = i.ToString() });
            }
            testArrayClass = testListClass.ToArray();
            testArrayStruct = testListStruct.ToArray();
        }

        [Benchmark]
        public int TestListClass()
        {
            var x = 0;
            foreach(var i in testListClass)
            {
                x += i.Text1.Length + i.Text3.Length;
            }
            return x;
        }

        [Benchmark]
        public int TestArrayClass()
        {
            var x = 0;
            foreach (var i in testArrayClass)
            {
                x += i.Text1.Length + i.Text3.Length;
            }
            return x;
        }

        [Benchmark]
        public int TestListStruct()
        {
            var x = 0;
            foreach (var i in testListStruct)
            {
                x += i.Text1.Length + i.Text3.Length;
            }
            return x;
        }

        [Benchmark]
        public int TestArrayStruct()
        {
            var x = 0;
            foreach (var i in testArrayStruct)
            {
                x += i.Text1.Length + i.Text3.Length;
            }
            return x;
        }

        [Benchmark]
        public int TestLinqClass()
        {
            var x = testListClass.Select(i=> i.Text1.Length + i.Text3.Length).Sum();
            return x;
        }

        [Benchmark]
        public int TestLinqStruct()
        {
            var x = testListStruct.Select(i => i.Text1.Length + i.Text3.Length).Sum();
            return x;
        }
    }

আপনি কী বুঝতে পেরেছেন যে তালিকাগুলি এবং এগুলি ব্যবহার করার সময় স্ট্রাইকগুলি কেন এত ধীর হয়? আপনার উল্লেখ করা লুকানো বক্সিং এবং আনবক্সিংয়ের কারণেই কি এটি? যদি তাই হয় তবে কেন হয়?
মার্কো গার্ডিনিক

অতিরিক্ত কোনও রেফারেন্সিংয়ের প্রয়োজন নেই বলে অ্যারে স্ট্রাক্ট অ্যাক্সেস করা দ্রুত হওয়া উচিত। বক্সিং / আনবক্সিং লিনকের ক্ষেত্রে।
রোমান পোক্রভস্কিজ

10

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

নোট করুন যে কোনও কাঠামোর ধরণের নকশা করা সম্ভব হয়েছে যাতে এটি মূলত শ্রেণীর ধরণের মতো আচরণ করবে, যদি কাঠামোর মধ্যে একটি প্রাইভেট শ্রেণীর ধরণের ক্ষেত্র থাকে এবং তার নিজের সদস্যদের মোড়কযুক্ত শ্রেণীর অবজেক্টের সাথে পুনঃনির্দেশ করে। উদাহরণস্বরূপ, কোনও PersonCollectionবৈশিষ্ট্য সরবরাহ করতে পারে SortedByNameএবং SortedByIdযার উভয়ই একটি "স্থাবর" রেফারেন্স ধারণ করে PersonCollection(তাদের নির্মাত্রে সেট করা হয়) এবং GetEnumeratorহয় কল করে creator.GetNameSortedEnumeratorবা প্রয়োগ করে creator.GetIdSortedEnumerator। এই ধরনের structs একটি একটি রেফারেন্স মত অনেক আচরণ করবে PersonCollectionছাড়া যে তাদের GetEnumeratorপদ্ধতিতে বিভিন্ন পদ্ধতি আবদ্ধ হবে PersonCollection। এক একটি কাঠামো একটি অ্যারের একটি অংশ মোড়ানো (যেমন এক একটি সংজ্ঞায়িত করতে পারে হতে পারে ArrayRange<T>কাঠামো যা রাখা হবে T[]বলা Arr, কোন intOffset , এবং একটি int- এLength, এমন একটি সূচকযুক্ত সম্পত্তি সহ যা idx0 থেকে সীমাতে থাকা কোনও সূচকের জন্য Length-1প্রবেশ করতে পারে Arr[idx+Offset])। দুর্ভাগ্যক্রমে, যদি fooএই জাতীয় কাঠামোর কেবল পঠনযোগ্য উদাহরণ হয় তবে বর্তমান সংকলক সংস্করণগুলি যেমন অপারেশনগুলিকে অনুমতি দেয় না foo[3]+=4;কারণ এ জাতীয় ক্রিয়াকলাপগুলি ক্ষেত্রগুলিতে লেখার চেষ্টা করবে কিনা তা নির্ধারণের তাদের কোনও উপায় নেই foo

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


10

নাহ - আমি পুরোপুরি নিয়মগুলির সাথে একমত নই। তারা পারফরম্যান্স এবং মানকতার সাথে বিবেচনা করার জন্য ভাল নির্দেশিকা, তবে সম্ভাবনার আলোকে নয়।

আপনি প্রতিক্রিয়াগুলিতে দেখতে পাচ্ছেন, এগুলি ব্যবহারের অনেক সৃজনশীল উপায় রয়েছে। সুতরাং, এই নির্দেশিকাগুলি কেবল সর্বদা পারফরম্যান্স এবং দক্ষতার জন্যই হওয়া দরকার।

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

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

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


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

যদি "3 ডি পয়েন্ট" প্রকারের স্পেসিফিকেশনটি ইঙ্গিত দেয় যে এর পুরো রাজ্যটি পঠনযোগ্য সদস্য x, y, এবং z এর মাধ্যমে প্রকাশিত হয়েছে doubleএবং সেই স্থানাঙ্কগুলির জন্য কোনও মানগুলির সংমিশ্রণ সহ একটি উদাহরণ তৈরি করা সম্ভব হয় , তবে এই ধরনের একটি বিবরণ এটি বাধ্যতামূলক করে একাধিক-থ্রেড আচরণের কিছু বিবরণ ব্যতীত এক্সপোজড-ফিল্ড স্ট্রাকচারের সাথে শব্দার্থগতভাবে অদৃশ্য আচরণ করুন (কিছু ক্ষেত্রে ক্ষেত্রে অপরিবর্তনীয় শ্রেণি আরও ভাল হবে, অন্যদিকে এক্সপোজড-ফিল্ড স্ট্রাক্ট আরও ভাল হবে; তথাকথিত "অপরিবর্তনীয়" কাঠামো হবে) প্রতিটি ক্ষেত্রে খারাপ হতে হবে)।
সুপারক্যাট

8

আমার নিয়ম

1, সর্বদা ক্লাস ব্যবহার করুন;

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


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

1
@ সুপের্যাট: আমি মনে করি যে এর জন্য মাইক্রোসফ্টকে দোষ দেওয়া সম্পূর্ণ ন্যায্য নয়। এখানে আসল সমস্যাটি হ'ল সি # একটি অবজেক্ট-ওরিয়েন্টেড ল্যাঙ্গুয়েজ হিসাবে কেবল সরল রেকর্ডের ধরণের উপর দৃষ্টি নিবদ্ধ করে না যা কেবলমাত্র অনেক আচরণ ছাড়াই ডেটা প্রকাশ করে। সি # কোনও পরিমাণে উদাহরণ নয় যেমন সি ++ হয় to যে হচ্ছে বললেন, আমি এছাড়াও বিশ্বাস খুব কম লোকই বিশুদ্ধ গলি প্রোগ্রাম, তাই সম্ভবত C # এর খুব আদর্শবাদী একটি ভাষা। (আমি সম্প্রতি একটির জন্য public readonlyআমার প্রকারের ক্ষেত্রগুলিও প্রকাশ করা শুরু করেছি, কারণ কেবলমাত্র পঠনযোগ্য বৈশিষ্ট্য তৈরি করা কার্যত কোনও লাভের জন্য খুব বেশি কাজ নয়))
স্টাকাক্স -

1
@ স্টাকেক্স: এ জাতীয় ধরণের "ফোকাস" করার দরকার নেই; তারা যা যথেষ্ট তা তাদের জন্য স্বীকৃতি দেওয়া। স্ট্রাক্টের ক্ষেত্রে সি # এর সাথে সবচেয়ে বড় দুর্বলতা এটি অন্যান্য অনেক ক্ষেত্রেও এটির বৃহত্তম সমস্যা: ভাষা যখন নির্দিষ্ট রূপান্তরগুলি উপযুক্ত বা উপযুক্ত না হয় তা নির্দেশ করার জন্য অপর্যাপ্ত সুযোগ-সুবিধা সরবরাহ করে এবং এই জাতীয় সুবিধার অভাব দুর্ভাগ্যজনক ডিজাইনের সিদ্ধান্তকে বহন করে। উদাহরণস্বরূপ, 99% "পরিবর্তনীয় স্ট্রাইটস অশুভ" সংকলকটির রূপান্তরিত হওয়া থেকে উদ্ভূত MyListOfPoint[3].Offset(2,3);হয় var temp=MyListOfPoint[3]; temp.Offset(2,3);, এটি রূপান্তরিত হয় যা প্রয়োগের সময়
নকল হয়

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

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

8

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

ক্লাস এবং স্ট্রাক্টস (সি # প্রোগ্রামিং গাইড)


কাঠামোগুলি ক্ষেত্রে ন্যাক্ট টেপ (যেমন কোনও পয়েন্টের স্থানাঙ্ক) এর সাথে কয়েকটি সম্পর্কিত-হলেও-স্বাধীন ভেরিয়েবলগুলি বেঁধে রাখা দরকার যেখানে স্ট্রাকচারগুলি খুব ভাল। এমএসডিএন নির্দেশিকাগুলি যুক্তিসঙ্গত হয় যদি কেউ যদি এমন কাঠামো তৈরির চেষ্টা করে যা অবজেক্টগুলির মতো আচরণ করে তবে সামগ্রিক নকশাকরণের সময় এটি কম কম উপযুক্ত হয়; তাদের মধ্যে কিছু পরের পরিস্থিতিতে প্রায় সঠিকভাবে ভুল are উদাহরণস্বরূপ, কোনও ধরণের দ্বারা আবদ্ধ ভেরিয়েবলগুলির স্বাধীনতার ডিগ্রি যত বেশি, অপরিবর্তনীয় শ্রেণির পরিবর্তে এক্সপোজড-ফিল্ড কাঠামো ব্যবহারের সুবিধা তত বেশি।
সুপারক্যাট

5

আমি মনে করি একটি ভাল প্রথম অনুমান "কখনও না"।

আমি মনে করি একটি ভাল দ্বিতীয় আনুমানিকতা হয় "কখনও না"।

আপনি যদি পারফের জন্য মরিয়া হন তবে সেগুলি বিবেচনা করুন তবে সর্বদা পরিমাপ করুন।


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

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

4
আমি মনে করি তারা Totin 'চিপ কার্ড (একটি সমতুল্য প্রয়োজন মনে en.wikipedia.org/wiki/Totin%27_Chip structs ব্যবহার জন্য)। সিরিয়াসলি।
গ্রেগ

4
একজন 87.5 কে ব্যক্তি কীভাবে উত্তর পোস্ট করে? ছোটবেলায় কি সে তা করেছে?
রোহিত ভিপিন ম্যাথিউজ

3
@ রোহিত - এটি ছয় বছর আগে ছিল; সাইটের মানগুলি তখন খুব আলাদা ছিল। এটি এখনও একটি খারাপ উত্তর, যদিও আপনি ঠিক বলেছেন।
অ্যান্ড্রু আর্নল্ড

5

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


1
এটি সবার সেরা ক্লু, আইএমএইচও।
ইভান

5

মিথ # 1: স্ট্র্যাক্টগুলি হ'ল লাইটওয়েট ক্লাস

এই মিথটি বিভিন্ন রূপে আসে। কিছু লোক বিশ্বাস করে যে মান ধরণের পদ্ধতি বা অন্যান্য উল্লেখযোগ্য আচরণ থাকতে পারে না বা থাকা উচিত। এগুলিকে কেবল সর্বজনীন ক্ষেত্র বা সাধারণ বৈশিষ্ট্য সহ সাধারণ ডেটা স্থানান্তর প্রকার হিসাবে ব্যবহার করা উচিত। ডেটটাইম টাইপটি এটির জন্য একটি ভাল কাউন্টারেরেক্সামাল: এটি কোনও সংখ্যার বা চরিত্রের মতো মৌলিক ইউনিট হিসাবে বিবেচনা করে এটির মান ধরণের হওয়ার জন্য এটি উপলব্ধি করে এবং এর ভিত্তিতে গণনা সম্পাদন করতে সক্ষম হওয়ার জন্য এটি বোধগম্যও হয় and এর মান। অন্য দিক থেকে জিনিসগুলির দিকে তাকানো, ডেটা ট্রান্সফার ধরণের ক্ষেত্রে প্রায়শই রেফারেন্স টাইপ হওয়া উচিত — সিদ্ধান্তটি পছন্দসই মান বা রেফারেন্স টাইপের শব্দার্থবিদ্যার উপর ভিত্তি করে হওয়া উচিত, ধরণের সরলতার নয় not অন্যান্য ব্যক্তিরা বিশ্বাস করেন যে পারফরম্যান্সের ক্ষেত্রে মান প্রকারগুলি রেফারেন্স ধরণের চেয়ে "হালকা"। সত্যটি হ'ল কিছু ক্ষেত্রে মানের ধরণগুলি আরও বেশি পারফরম্যান্ট হয় - যদি না বাক্স না দেওয়া হয় তবে তাদের আবর্জনা সংগ্রহের প্রয়োজন হয় না, ধরণের সনাক্তকরণের ওভারহেড না থাকে এবং উদাহরণস্বরূপ ডেরিফারেন্সিংয়ের প্রয়োজন হয় না। তবে অন্য উপায়ে, রেফারেন্সের ধরণগুলি আরও পারফরম্যান্ট — প্যারামিটার পাসিং, ভেরিয়েবলগুলিকে মান বরাদ্দ করা, মানগুলি ফেরানো, এবং অনুরূপ ক্রিয়াকলাপগুলি কেবল বোকোপিড করতে 4 বা 8 বাইট প্রয়োজন (আপনি 32-বিট বা 64-বিট সিএলআর চালাচ্ছেন কিনা তার উপর নির্ভর করে) ) সমস্ত ডেটা অনুলিপি না করে। কল্পনা করুন যে অ্যারেলিস্ট যদি কোনওভাবে "খাঁটি" মান ধরণের হয়ে থাকে এবং তার সমস্ত ডেটা অনুলিপি করার সাথে জড়িত কোনও পদ্ধতিতে অ্যারেলিস্ট এক্সপ্রেশনটি পাস করে! প্রায় সব ক্ষেত্রেই, পারফরম্যান্স যেভাবেই হোক না কেন এই ধরণের সিদ্ধান্তের দ্বারা সত্যই নির্ধারিত হয় না। বোতল নখগুলি কখনই হয় না আপনি যেখানে ভাবেন সেগুলি হবে এবং আপনি কার্য সম্পাদনের উপর ভিত্তি করে কোনও ডিজাইনের সিদ্ধান্ত নেওয়ার আগে, আপনি বিভিন্ন বিকল্প পরিমাপ করা উচিত। এটি লক্ষণীয় যে দুটি বিশ্বাসের সংমিশ্রণটিও কার্যকর হয় না। কোনও ধরণের কতগুলি পদ্ধতি রয়েছে তা বিবেচনাধীন নয় (এটি শ্রেণি বা কাঠামোই হোক) - উদাহরণ হিসাবে নেওয়া মেমরিটি প্রভাবিত হয় না। (কোডটি নিজেই গ্রহণের জন্য মেমোরির ক্ষেত্রে ব্যয় করতে হবে, তবে এটি প্রতিটি উদাহরণের চেয়ে একবার ব্যয় করেছে))

মিথ # 2: রেফারেন্স টাইপ THEগল উপর লাইভ; ভ্যালু টাইপ স্ট্যাক লাইভ

এটির প্রায়শই ব্যক্তির পক্ষ থেকে অলসতার কারণে ঘটে it প্রথম অংশটি সঠিক a একটি রেফারেন্স টাইপের একটি উদাহরণ সর্বদা গাদাতে তৈরি করা হয়। এটি দ্বিতীয় অংশ যা সমস্যার সৃষ্টি করে। যেমন আমি ইতিমধ্যে উল্লেখ করেছি যে কোনও ভেরিয়েবলের মান যেখানেই ঘোষিত হয় সেখানেই বেঁচে থাকে, সুতরাং আপনার যদি টাইপ ইন্টের উদাহরণ ভেরিয়েবল সহ একটি শ্রেণি থাকে তবে যে কোনও অবজেক্টের জন্য ভেরিয়েবলের মান সর্বদা সেখানে থাকবে যেখানে অবজেক্টের বাকী ডেটা থাকবে — গাদা উপর। কেবল স্থানীয় ভেরিয়েবল (পদ্ধতিগুলির মধ্যে ঘোষিত ভেরিয়েবল) এবং পদ্ধতির পরামিতিগুলি স্ট্যাকটিতে লাইভ। সি # 2 এবং তার পরেও কিছু স্থানীয় ভেরিয়েবলগুলি স্ট্যাকের উপরে সত্যই বাস করে না, আপনি যখন দেখবেন যে আমরা অধ্যায় 5 এ বেনাম পদ্ধতিগুলি দেখব তখন কি এই কনসপটগুলি এখনই অনুমোদিত? এটি বিতর্কযোগ্য যে আপনি যদি ম্যানেজড কোড লিখছেন তবে মেমরিটি কীভাবে সর্বোত্তমভাবে ব্যবহৃত হয় তা নিয়ে রানটাইমকে আপনার চিন্তিত হওয়া উচিত। প্রকৃতপক্ষে, ভাষার স্পেসিফিকেশন কোথা থেকে বাস করে সে সম্পর্কে কোনও গ্যারান্টি দেয় না; ভবিষ্যতের রানটাইম স্ট্যাকের উপরে কিছু অবজেক্ট তৈরি করতে সক্ষম হতে পারে যদি এটি জানে যে এটি এর সাথে সরে যেতে পারে, বা সি # সংকলক কোড জেনারেট করতে পারে যা স্ট্যাকটি মোটেই ব্যবহার করে না। পরবর্তী পৌরাণিক কাহিনীটি সাধারণত একটি পরিভাষা সংক্রান্ত সমস্যা।

মিথ # 3: লক্ষ্যগুলি সি দ্বারা # রেফারেন্সের মাধ্যমে পাস করা হয়েছে # খেলাপি দ্বারা

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

void AppendHello(StringBuilder builder)
{
    builder.Append("hello");
}

যখন এই পদ্ধতিটি বলা হয়, তখন প্যারামিটার মান (একটি স্ট্রিংবিল্ডারের একটি রেফারেন্স) মান দ্বারা পাস হয়। আপনি যদি পদ্ধতির মধ্যে বিল্ডার ভেরিয়েবলের মান পরিবর্তন করতে থাকেন example উদাহরণস্বরূপ, বিবৃতি দিয়ে বিল্ডার = নাল; - এই পরিবর্তনটি মিথের বিপরীতে, কলকারী দেখতে পাবেন না। এটি লক্ষণীয় যে আকর্ষণীয় কেবল মিথের "রেফারেন্স দ্বারা" বিটটিও সঠিক নয়, তবে "অবজেক্টগুলি পাস হয়ে গেছে" বিটটিও। বিষয়গুলি নিজেরাই রেফারেন্স বা মান দ্বারা পাস হয় না। যখন কোনও রেফারেন্স টাইপ জড়িত থাকে, হয় ভেরিয়েবলটি রেফারেন্স দ্বারা পাস হয় বা আর্গুমেন্টের (রেফারেন্স) মান দ্বারা পাস হয়। অন্য কিছুর পাশাপাশি, এটি ন্যূনতম উপ-মান হিসাবে যুক্তি হিসাবে ব্যবহৃত হলে কী হয় - এই প্রশ্নের উত্তর দেয় objects যদি বস্তুগুলি চারপাশে পাস করা হত, তবে এটি সমস্যার কারণ হয়ে দাঁড়াবে, কারণ সেখানে কোনও বস্তু পাস করার মতো হবে না! পরিবর্তে, নাল রেফারেন্সটি অন্য কোনও উল্লেখ হিসাবে একইভাবে মান দ্বারা পাস করা হয়। যদি এই দ্রুত ব্যাখ্যা আপনাকে বিস্মিত করে ফেলেছে, আপনি আমার নিবন্ধটি দেখতে চান, "সি # তে প্যারামিটারটি উত্তীর্ণ হচ্ছে" ()http://mng.bz/otVt ), যা আরও অনেক বিশদে যায়। এই পুরাণগুলি কেবল চারপাশে নয়। বক্সিং এবং আনবক্সিং তাদের ভুল বোঝাবুঝির ভাগের জন্য আসে, যা আমি পরে পরিষ্কার করার চেষ্টা করব।

তথ্যসূত্র: জন স্কিটির র গভীরতায় তৃতীয় সংস্করণে সি #


1
আপনি সঠিক বলে ধরে নিচ্ছেন খুব ভাল। একটি রেফারেন্স যোগ করতে খুব ভাল।
NoChance

4

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

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


3

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

http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/


3

কাঠামো বা মানের ধরণগুলি নিম্নলিখিত পরিস্থিতিতে ব্যবহার করা যেতে পারে -

  1. আপনি যদি আবশ্যকটিকে আবর্জনা সংগ্রহের মাধ্যমে সংগ্রহ করতে বাধা দিতে চান।
  2. যদি এটি একটি সাধারণ প্রকার এবং কোনও সদস্য ফাংশন তার উদাহরণ ক্ষেত্রগুলি পরিবর্তন করে না
  3. যদি অন্য ধরণের থেকে নেওয়া বা অন্য ধরণের থেকে প্রাপ্ত হওয়ার দরকার না থাকে।

আপনি এখানে এই লিঙ্কটিতে মান ধরণের এবং মানের ধরণের সম্পর্কে আরও জানতে পারেন


3

সংক্ষেপে, স্ট্রাক ব্যবহার করুন যদি:

1- আপনার অবজেক্টের বৈশিষ্ট্য / ক্ষেত্রগুলি পরিবর্তন করার দরকার নেই। আমার অর্থ আপনি কেবল তাদের প্রাথমিক মান দিতে চান এবং তারপরে সেগুলি পড়তে চান।

2- আপনার বস্তুর বৈশিষ্ট্য এবং ক্ষেত্রগুলি মান ধরণের এবং সেগুলি এত বড় নয়।

যদি সে ক্ষেত্রে হয় তবে আপনি আরও ভাল পারফরম্যান্স এবং অনুকূলিত মেমরি বরাদ্দের জন্য স্ট্রাইকগুলির সুবিধা নিতে পারেন কারণ তারা স্ট্যাক এবং হ্যাপ উভয়ের চেয়ে কেবল স্ট্যাক ব্যবহার করে (ক্লাসে)


2

আমি জিনিসগুলির জন্য খুব কমই কোনও কাঠামো ব্যবহার করি। তবে তা কেবল আমিই। এটি নির্ভর করে যে আমার অবজেক্টটি আড়াল করার দরকার আছে কিনা।

অন্যান্য উত্তরে যেমন বলা হয়েছে, আমি বাস্তব-বিশ্বের বস্তুর জন্য ক্লাস ব্যবহার করি। আমার কাছে স্ট্রাক্টের মানসিকতাও অল্প পরিমাণে ডেটা সঞ্চয় করার জন্য ব্যবহৃত হয়।


-11

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


2
কাঠামোগুলি উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে না, দেখুন msdn.microsoft.com/en-us/library/0taef578.aspx
HimBromBeere
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.