c# কেন তালিকা থেকে উত্তরাধিকার<টি>?




.net list (21)

এই composition বনাম inheritance একটি ক্লাসিক উদাহরণ।

এই নির্দিষ্ট ক্ষেত্রে:

দল যোগ আচরণ সঙ্গে খেলোয়াড়দের একটি তালিকা

অথবা

খেলোয়াড়দের একটি তালিকা ধারণ করে দলটি তার নিজস্ব একটি বস্তু।

তালিকাটি বর্ধিত করে আপনি কয়েকটি উপায়ে নিজেকে সীমিত করছেন:

  1. আপনি অ্যাক্সেস সীমাবদ্ধ করতে পারবেন না (উদাহরণস্বরূপ, রস্টার পরিবর্তনকারী ব্যক্তিদের থামানো)। আপনার সমস্ত তালিকা পদ্ধতিগুলি আপনার প্রয়োজন কিনা তা চান না।

  2. আপনি যদি অন্যান্য জিনিসের তালিকাও চান তবে কী হবে। উদাহরণস্বরূপ, দলের কোচ, ম্যানেজার, ভক্ত, সরঞ্জাম ইত্যাদি আছে। তাদের মধ্যে কয়েকজন নিজেরাই সঠিকভাবে তালিকাভুক্ত হতে পারে।

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

রচনা - আপনার অবজেক্টের ভিতরে থাকা এমন আচরণ সহ একটি বস্তু সহ।

উত্তরাধিকার - আপনার বস্তু এমন বস্তুর একটি দৃষ্টান্ত হয়ে দাঁড়ায় যার আপনার আচরণ রয়েছে।

উভয় তাদের ব্যবহার আছে, কিন্তু সংযোজন আরও ভাল যেখানে এই একটি পরিষ্কার ক্ষেত্রে।

আমার প্রোগ্রামগুলি পরিকল্পনা করার সময়, আমি প্রায়শই চিন্তার চেইন দিয়ে শুরু করি:

একটি ফুটবল দল শুধুমাত্র ফুটবল খেলোয়াড়দের একটি তালিকা। অতএব, আমি এটা দিয়ে প্রতিনিধিত্ব করা উচিত:

var football_team = new List<FootballPlayer>();

এই তালিকার অর্ডারগুলি ক্রম অনুসারে প্লেয়ারগুলিতে তালিকাভুক্ত হওয়া ক্রমের প্রতিনিধিত্ব করে।

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

তাই আমি মনে করি:

ঠিক আছে, একটি ফুটবল দল শুধুমাত্র খেলোয়াড়দের একটি তালিকা হিসাবে, তবে অতিরিক্ত, এটি একটি নাম (একটি string ) এবং স্কোরগুলির চলমান মোট (একটি int ) থাকে। .NET ফুটবল দল সংরক্ষণের জন্য একটি ক্লাস সরবরাহ করে না, তাই আমি নিজের ক্লাস তৈরি করব। সবচেয়ে অনুরূপ এবং প্রাসঙ্গিক বিদ্যমান গঠন List<FootballPlayer> , তাই আমি এটি থেকে উত্তরাধিকারী হবে:

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}

কিন্তু এটি নির্দেশ করে যে একটি নির্দেশিকা আপনাকে List<T> থেকে উত্তরাধিকারী হতে হবে না । আমি পুঙ্খানুপুঙ্খভাবে এই নির্দেশিকা দ্বারা বিভ্রান্ত করছি দুটি ক্ষেত্রে।

কেন না?

দৃশ্যত List কর্মক্ষমতা জন্য অনুকূলভাবে অপ্টিমাইজ করা হয় । তা কেমন করে? আমি List প্রসারিত হলে কি কর্মক্ষমতা সমস্যা হবে? ঠিক কি ভাঙ্গবে?

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

কেন এটা এমনকি কোন ব্যাপার না? একটি তালিকা একটি তালিকা। সম্ভবত কি পরিবর্তন হতে পারে? আমি কি সম্ভবত পরিবর্তন করতে চান?

এবং শেষ পর্যন্ত, যদি মাইক্রোসফ্ট আমাকে List থেকে উত্তরাধিকারী না করতে চায়, তাহলে তারা কেন ক্লাস sealed ?

আমি আর কি ব্যবহার করতে অনুমিত হয়?

দৃশ্যত, কাস্টম সংগ্রহের জন্য, মাইক্রোসফ্ট একটি Collection শ্রেণী সরবরাহ করেছে যা List পরিবর্তে বর্ধিত করা উচিত। কিন্তু এই ক্লাসটি খুব বেয়ার এবং উদাহরণস্বরূপ AddRange হিসাবে অনেক দরকারী জিনিস নেই। jvitor83 এর উত্তরটি সেই বিশেষ পদ্ধতির জন্য একটি কর্মক্ষমতা রেশনেল সরবরাহ করে, তবে কোনও AddRange চেয়ে ধীর AddRange কীভাবে ভাল নয়?

Collection থেকে উত্তরণ List থেকে উত্তরাধিকার চেয়ে উপায় বেশি কাজ, এবং আমি কোন সুবিধা দেখতে। নিশ্চিতভাবেই মাইক্রোসফ্ট আমাকে কোনও কারণে অতিরিক্ত কাজ করতে বলবে না, তাই আমি অনুভব করতে পারছি না যে আমি কিছুটা ভুল বুঝি, এবং উত্তরাধিকার Collection আসলে আমার সমস্যাটির সঠিক সমাধান নয়।

আমি IList বাস্তবায়ন যেমন পরামর্শ দেখেছি। শুধুমাত্র না. এই boilerplate কোড লাইন কয়েক ডজন যা আমাকে কিছুই লাভ।

শেষ পর্যন্ত, কিছু কিছুতে List মোড়ানো প্রস্তাব করে:

class FootballTeam 
{ 
    public List<FootballPlayer> Players; 
}

এই দুটি সমস্যা আছে:

  1. এটা আমার কোড অযথা verbose করে তোলে। আমি এখন my_team.Players.Count হবে পরিবর্তে শুধু my_team.Count কল। সৌভাগ্যক্রমে, সি # দিয়ে সূচীগুলিকে স্বচ্ছ করে তুলতে এবং অভ্যন্তরীণ তালিকাগুলির সমস্ত পদ্ধতিগুলিকে এগিয়ে নিয়ে যেতে সূচীগুলিকে সংজ্ঞায়িত করতে পারি ... তবে এটি অনেক কোড! আমি যে কাজ জন্য কি পেতে পারি?

  2. এটা শুধু প্লেইন কোন ধারনা না। একটি ফুটবল দল খেলোয়াড়দের একটি তালিকা "আছে" না। এটা খেলোয়াড়দের তালিকা। আপনি বলবেন না "জন ম্যাকফুটবলার কিছুটা খেলোয়াড়ের সাথে যোগ দিয়েছেন"। আপনি বলছেন "জন কিছুটাতে যোগ দিয়েছে"। আপনি "স্ট্রিং এর অক্ষর" তে একটি অক্ষর যোগ করেন না, আপনি একটি স্ট্রিংটিতে একটি অক্ষর যুক্ত করেন। আপনি লাইব্রেরীর বইগুলিতে একটি বই যুক্ত করেন না, আপনি লাইব্রেরিতে একটি বই যোগ করেন।

আমি বুঝতে পারি যে "হুডের নিচে" কি "Y এর অভ্যন্তরীণ তালিকায় যোগ করা" বলে মনে করা যেতে পারে, কিন্তু এটি বিশ্ব সম্পর্কে চিন্তাভাবনা করার মত একটি অত্যন্ত পাল্টা-বুদ্ধিমান উপায় বলে মনে হয়।

আমার প্রশ্ন (সারসংক্ষেপ)

কোনও তথ্য কাঠামোর প্রতিনিধিত্ব করার সঠিক C # উপায় যা "যৌক্তিকভাবে" (অর্থাৎ "মানুষের মনকে" বলা হয়) কেবল কয়েক ঘন্টাধ্বনি এবং সিঁড়ির সাথে things একটি list ?

List<T> থেকে উত্তরাধিকারী List<T> সর্বদা অগ্রহণযোগ্য? এটা গ্রহণযোগ্য যখন? কেন কেন না? List<T> থেকে না উত্তরাধিকারী কিনা তা নির্ধারণ করার সময় কোন প্রোগ্রামার বিবেচনা করতে হবে?


ইহা পারিপার্শ্বিক অবস্থা উপর নির্ভর করে

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

অস্পষ্ট শব্দবিজ্ঞান

সুতরাং, তার খেলোয়াড়দের তালিকা হিসাবে একটি দল বিবেচনা করার সাথে সমস্যাটি যে তার শব্দার্থিক প্রসঙ্গের উপর নির্ভর করে এবং প্রসঙ্গ পরিবর্তন করার সময় এটি বর্ধিত করা যাবে না। উপরন্তু এটি প্রকাশ করা কঠিন, আপনি কোন প্রসঙ্গ ব্যবহার করছেন।

ক্লাস এক্সটেনসিবল হয়

যখন আপনি শুধুমাত্র একটি সদস্য (উদাহরণস্বরূপ IList activePlayers) সহ একটি বর্গ ব্যবহার করেন, তখন আপনি প্রসঙ্গটি পরিষ্কার করতে সদস্যের নামটি ব্যবহার করতে পারেন (এবং এর সাথে তার মন্তব্য)। অতিরিক্ত প্রসঙ্গ আছে, আপনি শুধু একটি অতিরিক্ত সদস্য যোগ করুন।

ক্লাস আরো জটিল

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

উপসংহার / বিবেচ্য বিষয়

যখন আপনার খুব নির্দিষ্ট প্রসঙ্গ থাকে, তখন খেলোয়াড়দের তালিকা হিসাবে একটি দল বিবেচনা করা ঠিক। উদাহরণস্বরূপ একটি পদ্ধতির ভিতরে এটি লিখতে ঠিক আছে

IList<Player> footballTeam = ...

F # ব্যবহার করার সময়, এটি একটি টাইপ সংক্ষেপে তৈরি করতেও ঠিক থাকতে পারে

type FootballTeam = IList<Player>

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


ক্লাস উপর ইন্টারফেস পছন্দ

ক্লাস ক্লাস থেকে deriving এড়াতে এবং পরিবর্তে প্রয়োজনীয় অন্তর্বর্তী ইন্টারফেস বাস্তবায়ন করা উচিত।

উত্তরাধিকার বিরতি Encapsulation

ক্লাস বিরতি encapsulation থেকে deriving :

  • আপনার সংগ্রহ কিভাবে বাস্তবায়িত হয় সে সম্পর্কে অভ্যন্তরীণ বিশদ প্রকাশ করে
  • একটি ইন্টারফেস (পাবলিক ফাংশন এবং বৈশিষ্ট্যের সেট) ঘোষণা করে যা উপযুক্ত নাও হতে পারে

অন্যান্য জিনিসগুলির মধ্যে এটি আপনার কোডকে পুনরায় সংশোধন করা কঠিন করে তোলে।

ক্লাস একটি বাস্তবায়ন বিস্তারিত

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

ধারণাগতভাবে যে তথ্যটি System.List"তালিকা" বলা হয় তা লাল-হেরিংয়ের একটি বিট। A System.List<T>একটি পরিবর্তনযোগ্য অর্ডার সংগ্রহ যা উপাদানগুলি যুক্ত, সন্নিবেশ, এবং সরানোর জন্য এম্টরাইজড O (1) অপারেশনগুলিকে সমর্থন করে এবং উপাদানগুলির সংখ্যা পুনরুদ্ধার বা সূচী দ্বারা উপাদানটি পাওয়ার এবং সেট করার জন্য O (1) অপারেশনগুলিকে সমর্থন করে।

ক্ষুদ্রতর ইন্টারফেসটি আরও বেশি নমনীয় কোড

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

কিভাবে ইন্টারফেস চয়ন করুন

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

এই প্রক্রিয়াটি পরিচালনা করতে সহায়তা করতে পারে এমন কিছু প্রশ্ন:

  • আমার কি গণনা দরকার? বাস্তবায়ন বিবেচনা না করা হলেIEnumerable<T>
  • এই সংগ্রহটি চালু হওয়ার পরে কি এটি পরিবর্তন হচ্ছে? বিবেচনা না করা হলে IReadonlyList<T>
  • আমি সূচক দ্বারা আইটেম অ্যাক্সেস করতে পারেন যে এটা গুরুত্বপূর্ণ? বিবেচনাICollection<T>
  • আমি ক্রম আইটেম সংগ্রহ যা ক্রম গুরুত্বপূর্ণ? হয়তো এটা একটা ISet<T>?
  • আপনি যদি সত্যিই এই জিনিস চান তাহলে এগিয়ে যান এবং বাস্তবায়ন IList<T>

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

এই পদ্ধতিটি গ্রহণ করে আপনি কোডটি পড়তে, রিফ্যাক্টর এবং পুনঃব্যবহার করা সহজ পাবেন।

Boilerplate এড়ানো সম্পর্কে নোট

একটি আধুনিক আইডিই মধ্যে ইন্টারফেস বাস্তবায়ন করা সহজ হওয়া উচিত। ডান ক্লিক করুন এবং "ইন্টারফেস বাস্তবায়ন" নির্বাচন করুন। তারপর প্রয়োজন হলে সদস্য শ্রেণীতে সব বাস্তবায়ন এগিয়ে।

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

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


সবাই যেমন উল্লেখ করেছেন, খেলোয়াড়দের একটি দল খেলোয়াড়দের তালিকা নয়। এই ভুলটি সর্বত্র অনেক লোকের দ্বারা তৈরি করা হয়, সম্ভবত দক্ষতার বিভিন্ন স্তরে। প্রায়ই সমস্যা সূক্ষ্ম এবং মাঝে মাঝে খুব স্থূল, এই ক্ষেত্রে হিসাবে। এই ডিজাইনগুলি খারাপ কারণ এটি লস্কোভ প্রতিস্থাপন নীতি লঙ্ঘন করে। এই ধারণাটি ব্যাখ্যা করার জন্য ইন্টারনেটে অনেক ভাল নিবন্ধ রয়েছে যেমন, http://en.wikipedia.org/wiki/Liskov_substitution_principle

সংক্ষেপে, ক্লাসের মধ্যে একটি পিতামাতা / শিশু সম্পর্কের মধ্যে সংরক্ষিত দুটি নিয়ম রয়েছে:

  • একটি সন্তানের পিতামাতার সম্পূর্ণরূপে সংজ্ঞায়িত চেয়ে কম কোন চরিত্রগত প্রয়োজন হবে।
  • একটি সন্তানের সম্পূর্ণরূপে শিশুর সংজ্ঞায়িত ছাড়াও কোন চরিত্রগত প্রয়োজন হবে।

অন্য কথায়, একটি সন্তানের একটি শিশুর একটি প্রয়োজনীয় সংজ্ঞা, এবং একটি সন্তানের একটি পিতামাতার যথেষ্ট সংজ্ঞা।

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

  • একটি ফুটবল দল ফুটবল খেলোয়াড়দের একটি তালিকা? (একটি তালিকা সব বৈশিষ্ট্য একই অর্থ একটি দলের প্রয়োগ)
    • একটি দল homogenous সত্তা একটি সংগ্রহ? হ্যাঁ, দল খেলোয়াড়দের একটি সংগ্রহ
    • দলের রাষ্ট্রের বর্ণনামূলক খেলোয়াড়দের অন্তর্ভুক্ত করার আদেশ কি দলটি নিশ্চিত করে যে ক্রমটি পরিবর্তিত না হওয়া পর্যন্ত ক্রমটি সংরক্ষিত হয়? না, এবং না
    • খেলোয়াড়দের মধ্যে তাদের sequencial অবস্থান উপর ভিত্তি করে অন্তর্ভুক্ত / বাদ দেওয়া প্রত্যাশিত হয়? না

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

এই মুহুর্তে আমি মন্তব্য করতে চাই যে টিম ক্লাসটি আমার মতে, একটি তালিকা ব্যবহার করেও বাস্তবায়িত হবে না; এটি বেশিরভাগ ক্ষেত্রে সেট সেট স্ট্রাকচার (উদাহরণস্বরূপ হ্যাশসেট) ব্যবহার করে প্রয়োগ করা উচিত।


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

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


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

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

সম্ভবত, একটি PlayerCollection betters ধারণা আপনার পছন্দের পদ্ধতির suits?

public class PlayerCollection : Collection<Player> 
{ 
}

এবং তারপর ফুটবলটাইম এটি দেখতে পারেন:

public class FootballTeam 
{ 
    public string Name { get; set; }
    public string Location { get; set; }

    public ManagementCollection Management { get; protected set; } = new ManagementCollection();

    public CoachingCollection CoachingCrew { get; protected set; } = new CoachingCollection();

    public PlayerCollection Players { get; protected set; } = new PlayerCollection();
}

নকশা> বাস্তবায়ন

আপনি কি পদ্ধতি এবং বৈশিষ্ট্য প্রকাশ করা একটি নকশা সিদ্ধান্ত। আপনি থেকে উত্তরাধিকার বেস বেস একটি বাস্তবায়ন বিস্তারিত। আমি এটা প্রাক্তন ফিরে একটি পদক্ষেপ নিতে মূল্য মনে হয়।

একটি বস্তু তথ্য এবং আচরণ একটি সংগ্রহ।

সুতরাং আপনার প্রথম প্রশ্ন হওয়া উচিত:

  • এই বস্তুটি আমি তৈরি করছি এমন মডেলটিতে কোন তথ্যটি অন্তর্ভুক্ত করে?
  • কি আচরণ এই বস্তু প্রদর্শন করা হয় যে মডেল?
  • কিভাবে ভবিষ্যতে এই পরিবর্তন হতে পারে?

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

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

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

ডিজাইন স্পেসিফিকেসন বিবেচনা করুন

MSDN বা ভিজ্যুয়াল স্টুডিওতে তালিকা <টি> এবং IList <T> এ একবার দেখুন। তারা প্রকাশ করা কি পদ্ধতি এবং বৈশিষ্ট্য দেখুন। এই পদ্ধতিগুলি কি কেউ আপনার মতামত ফুটবলটাইমকে করতে চান এমন কিছু দেখতে চান?

ফুটবল টিম। রিভার্স () আপনার কাছে ধারনা করে? FootballTeam.ConvertAll <টুপুট> () আপনি চান এমন কিছু দেখতে চান?

এটি একটি কৌতুক প্রশ্ন নয়; উত্তর প্রকৃতপক্ষে "হ্যাঁ" হতে পারে। আপনি তালিকা <প্লেয়ার> বা IList <প্লেয়ার> প্রয়োগ / উত্তরাধিকারী হন, তবে আপনি তাদের সাথে আটকে আছেন; যদি আপনার মডেলের জন্য এটি আদর্শ, তা করুন।

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

class FootballTeam : ... ICollection<Player>
{
    ...
}

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

class FootballTeam ...
{
    public ICollection<Player> Players { get { ... } }
}

আপনি হয়তো মনে করতে পারেন যে আপনি কেবলমাত্র তাদের গণনা করার পরিবর্তে খেলোয়াড়দের সেটকে গণনা করতে, তাদের যুক্ত করতে বা অপসারণ করতে সক্ষম হবেন। IEnumerable <প্লেয়ার> বিবেচনা করার জন্য একটি পুরোপুরি বৈধ বিকল্প।

আপনি হয়ত মনে করতে পারেন যে এই ইন্টারফেসগুলির মধ্যে কোনটি আপনার মডেলে উপকারী নয়। এটি কম সম্ভাবনাময় (আয়তনযোগ্য <টি> অনেক ক্ষেত্রে কার্যকর) তবে এটি এখনও সম্ভব।

যে কেউ আপনাকে বলবে যে এটির মধ্যে একটি এটি স্পষ্টভাবে এবং নিশ্চিতভাবেই ভুল ক্ষেত্রে প্রতিটি ক্ষেত্রে বিভ্রান্ত। যে কেউ যিনি তোমাকে বলতে এটা সুনিশ্চিতভাবে এবং নিশ্চিতভাবেই হয় প্রচেষ্টা অধিকার প্রতিটি ক্ষেত্রে বিপথে চালিত হয়।

বাস্তবায়ন উপর সরানো

একবার আপনি তথ্য এবং আচরণের সিদ্ধান্ত নিয়েছেন, আপনি বাস্তবায়ন সম্পর্কে সিদ্ধান্ত নিতে পারেন। এই উত্তরাধিকার বা রচনা মাধ্যমে আপনি নির্ভর করে কোন কংক্রিট ক্লাস রয়েছে।

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

একটি চিন্তাধারা পরীক্ষা

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

class FootballTeam : ... ICollection<Player>, 
                         ICollection<StaffMember>,
                         ICollection<Score>
{
    ....
}

ডিজাইনটি সত্ত্বেও, C # এ এই স্থানে আপনি তালিকা <টি> থেকে উত্তরাধিকারসূত্রে এই সমস্তগুলি বাস্তবায়ন করতে পারবেন না, কারণ C # "শুধুমাত্র" একক উত্তরাধিকারকে সমর্থন করে। (যদি আপনি C ++ এ এই malarky চেষ্টা করেছেন, তবে আপনি এটি একটি ভাল জিনিস বিবেচনা করতে পারেন।) উত্তরাধিকারের মাধ্যমে একটি সংগ্রহ বাস্তবায়ন করা এবং সংকলনের মাধ্যমে একটিকে মলিন মনে হতে পারে । এবং আইলিস্ট <প্লেয়ার> প্রয়োগ না করা পর্যন্ত গণনা হিসাবে বৈশিষ্ট্যগুলি ব্যবহারকারীদের বিভ্রান্তিকর হয়ে ওঠে .কাউন্ট এবং IList <StaffMember> .খাত ইত্যাদি স্পষ্টভাবে, এবং তারপর তারা বিভ্রান্তিকর পরিবর্তে শুধু বেদনাদায়ক। আপনি এই যাচ্ছে যেখানে দেখতে পারেন; এই উপায়ে চিন্তাভাবনা করার সময় অন্তরঙ্গ অনুভূতি আপনাকে ভালভাবে বলতে পারে যে এই দিকটিতে মাথা খারাপ মনে হচ্ছে (এবং সঠিকভাবে বা ভুলভাবে, আপনার সহকর্মীরাও যদি এটিকে বাস্তবায়ন করেন!)

সংক্ষিপ্ত উত্তর (খুব লম্বা)

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


ফুটবলটাইমের প্রধান দলের সাথে রিজার্ভ টিম থাকলে কী হবে?

class FootballTeam
{
    List<FootballPlayer> Players { get; set; }
    List<FootballPlayer> ReservePlayers { get; set; }
}

আপনি যে কিভাবে মডেল হবে?

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}

সম্পর্ক স্পষ্টভাবে আছে এবং একটি হয় না।

নাকি RetiredPlayers ?

class FootballTeam
{
    List<FootballPlayer> Players { get; set; }
    List<FootballPlayer> ReservePlayers { get; set; }
    List<FootballPlayer> RetiredPlayers { get; set; }
}

থাম্ব একটি নিয়ম হিসাবে, আপনি যদি কখনও সংগ্রহ থেকে উত্তরাধিকার করতে চান, ক্লাস SomethingCollection নাম।

আপনার SomethingCollection semantically ইন্দ্রিয় তোলে? আপনার টাইপ Something সংগ্রহ যদি শুধুমাত্র এই কাজ।

ফুটবলটাইম ক্ষেত্রে এটি সঠিক নয়। একটি Team একটি Collection চেয়ে বেশি। কোচ, প্রশিক্ষক ইত্যাদি একটি Team থাকতে পারে যেমন অন্য উত্তরগুলি উল্লেখ করেছে।

FootballCollection কলেকশন ফুটবলের সংগ্রহের মতো বা ফুটবলের উপাদান সংগ্রহের মতো শোনাচ্ছে। TeamCollection , দলগুলোর একটি সংগ্রহ।

FootballPlayerCollection এমন খেলোয়াড়দের সংগ্রহের মতো শোনাচ্ছে যা List<FootballPlayer> থেকে উত্তরাধিকারী একটি শ্রেণির জন্য বৈধ নাম হবে যদি আপনি সত্যিই এটি করতে চান।

সত্যিই List<FootballPlayer> সঙ্গে মোকাবিলা করার জন্য একটি পুরোপুরি ভাল টাইপ। হয়তো IList<FootballPlayer> যদি আপনি এটি একটি পদ্ধতি থেকে ফিরে আসছেন।

সংক্ষেপে

নিজেকে জিজ্ঞাসা করুন

  1. X একটি Y ? অথবা X একটি Y ?

  2. আমার ক্লাস নাম কি তারা মানে?


এখানে কিছু ভাল উত্তর আছে। আমি তাদের নিম্নলিখিত পয়েন্ট যোগ হবে।

কোনও তথ্য কাঠামোর প্রতিনিধিত্ব করার সঠিক C # উপায় যা "যৌক্তিকভাবে" (অর্থাৎ "মানুষের মনকে" বলা হয়) কেবল কয়েক ঘন্টাধ্বনি এবং সিঁড়ির সাথে জিনিসগুলির একটি তালিকা?

ফাঁকা পূরণ করতে ফুটবলের অস্তিত্ব সম্পর্কে পরিচিত দশজন কম্পিউটার ব্যবহারকারী প্রোগ্রামারকে জিজ্ঞাসা করুন:

A football team is a particular kind of _____

কেউ কি বললো "কয়েক ঘণ্টা এবং সিঁড়ি দিয়ে ফুটবল খেলোয়াড়দের তালিকা", নাকি তারা সবাই "স্পোর্টস টিম" বা "ক্লাব" বা "সংস্থা" বলে? আপনার ধারণার যে ফুটবল দলগুলি একটি বিশেষ ধরণের খেলোয়াড়ের তালিকা আপনার মনুষ্যসৃষ্টিতে এবং আপনার মনুষ্য মনের মধ্যে।

List<T> একটি প্রক্রিয়া । ফুটবল দলটি একটি ব্যবসায়িক অবজেক্ট - অর্থাৎ, এমন একটি অবজেক্ট যা প্রোগ্রামের ব্যবসায়িক ডোমেনে কিছু ধারণা উপস্থাপন করে। যারা মিশ্রিত করবেন না! একটি ফুটবল দল এক ধরনের দল; এটি একটি রস্টার আছে, একটি রস্টার খেলোয়াড়দের একটি তালিকা । একটি রস্টার খেলোয়াড়দের একটি নির্দিষ্ট ধরনের তালিকা নয় । একটি রস্টার খেলোয়াড়দের একটি তালিকা। সুতরাং Roster নামক একটি সম্পত্তি তৈরি করুন যা একটি List<Player> । এবং এটি কেবলমাত্র ReadOnlyList<Player> যখন আপনি এটিতে থাকবেন, যদি না আপনি বিশ্বাস করেন যে ফুটবল টিমের সম্পর্কে যারা জানে তারা সবাই রস্টার থেকে খেলোয়াড়দের মুছে ফেলবে।

List<T> থেকে উত্তরাধিকারী List<T> সর্বদা অগ্রহণযোগ্য?

কে অগ্রহণযোগ্য? আমাকে? না।

এটা গ্রহণযোগ্য যখন?

যখন আপনি এমন একটি প্রক্রিয়া তৈরি করছেন যা List<T> প্রক্রিয়াটি প্রসারিত করে

List<T> থেকে না উত্তরাধিকারী কিনা তা নির্ধারণ করার সময় কোন প্রোগ্রামার বিবেচনা করতে হবে?

আমি একটি প্রক্রিয়া বা একটি ব্যবসায়িক বস্তু নির্মাণ করছি?

কিন্তু যে কোড অনেক! আমি যে কাজ জন্য কি পেতে পারি?

আপনি আপনার প্রশ্ন টাইপ করার জন্য আরো সময় ব্যয় করেছেন যে List<T> পঞ্চাশ বারের প্রাসঙ্গিক সদস্যদের জন্য এটি আপনাকে ফরওয়ার্ডিং পদ্ধতি লিখতে নিয়েছেন। আপনি স্পষ্টভাবে ভয়ঙ্করতা থেকে ভীত নন, এবং আমরা এখানে কোডের খুব কম পরিমাণে কথা বলছি; এই কয়েক মিনিট কাজ।

হালনাগাদ

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

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


আইফেলের উদ্ভাবক এবং চুক্তি অনুসারে ডিজাইনের বেত্রাণ্ড মেয়েরকে আমি কেবল যুক্ত করতে চেয়েছিলাম, এটি একটি চোখের প্যাটার্ন ব্যাটিংয়ের মতোই Teamউত্তরাধিকারী হবে List<Player>

তার বই, অবজেক্ট-ওরিয়েন্টেড সফটওয়্যার নির্মাণে , তিনি একটি GUI সিস্টেম বাস্তবায়ন নিয়ে আলোচনা করেন যেখানে আয়তক্ষেত্রাকার উইন্ডোতে শিশু উইন্ডো থাকতে পারে। তিনি কেবল হয়েছে Windowউভয় থেকে উত্তরাধিকারী Rectangleএবং Tree<Window>বাস্তবায়ন পুনরায় ব্যবহার করার জন্য।

তবে, সি # আইফেল নয়। পরেরটি একাধিক উত্তরাধিকার এবং বৈশিষ্ট্য পুনর্নাম সমর্থন করে । সি #, যখন আপনি উপবিষ্ট, আপনি ইন্টারফেস এবং প্রয়োগ উভয় উত্তরাধিকারী। আপনি বাস্তবায়ন override করতে পারেন, কিন্তু কলিং কনভেনশন সরাসরি superclass থেকে কপি করা হয়। আইফেল তবে আপনি পাবলিক পদ্ধতির নাম পরিবর্তন করতে পারেন, তাই আপনি নাম পরিবর্তন করতে পারেন Addএবং Removeকরতে Hireএবং Fireআপনার Team। যদি একটি উদাহরণ Teamফিরে আপcast হয় List<Player>, কলার এটি ব্যবহার Addএবং Removeসংশোধন করতে হবে, কিন্তু আপনার ভার্চুয়াল পদ্ধতি Hireএবং Fireবলা হবে।


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


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

এটি একটি কঠোর নিয়ম, যদি আপনি একটি পাবলিক API টি লিখেন , বা অন্য কোনও কোড ব্যবহার করেন যা অনেক লোকের দ্বারা ব্যবহৃত হবে। আপনার যদি একটি ছোট অ্যাপ্লিকেশন থাকে এবং 2 টিরও বেশি ডেভেলপার থাকে তবে আপনি এই নিয়মটি উপেক্ষা করতে পারেন। এটি আপনাকে কিছু সময় বাঁচাবে।

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


এখানে অনেক চমৎকার উত্তর রয়েছে, কিন্তু আমি এমন কিছু স্পর্শ করতে চাই যা আমি উল্লেখ করিনি: অবজেক্ট ভিত্তিক নকশা বস্তুকে ক্ষমতায়নের বিষয়ে ।

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

যখন আপনি উত্তরাধিকারী হন List, অন্য সমস্ত বস্তু আপনাকে তালিকা হিসাবে দেখতে পারেন। তারা প্লেয়ার যোগ এবং অপসারণ করার পদ্ধতি সরাসরি এক্সেস আছে। এবং আপনি আপনার নিয়ন্ত্রণ হারিয়ে গেছে; উদাহরণ স্বরূপ:

ধরুন, কোন খেলোয়াড় অবসরপ্রাপ্ত, পদত্যাগ করেছেন বা বহিস্কার করা হয়েছে কিনা তা জানার মাধ্যমে আপনি কোনও খেলোয়াড়কে আলাদা করতে চান। আপনি RemovePlayerএকটি উপযুক্ত ইনপুট enum লাগে যে একটি পদ্ধতি বাস্তবায়ন করতে পারে । যাইহোক, উত্তরাধিকার দ্বারা List, আপনি সরাসরি অ্যাক্সেস প্রতিরোধ করতে পারবেন Remove, RemoveAllএমনকি Clear। ফলস্বরূপ, আপনি আসলে আপনার ক্লাস disempowered করেছি FootballTeam

Encapsulation উপর অতিরিক্ত চিন্তা ... আপনি নিম্নলিখিত উদ্বেগ উত্থাপিত:

এটা আমার কোড অযথা verbose করে তোলে। আমি এখন my_team.players.Count করতে হবে পরিবর্তে শুধু my_team কল।

আপনি সঠিক, সমস্ত ক্লায়েন্টদের আপনি দলের ব্যবহার করার জন্য অযথাযথভাবে verbose হবে। তবে, সমস্যাটির তুলনায় এটি খুব ছোট এবং List Playersআপনি সবার কাছে উন্মুক্ত হয়েছেন যাতে তারা আপনার সম্মতি ছাড়াই আপনার দলের সাথে খারাপ আচরণ করতে পারে।

আপনি বলতে যান:

এটা শুধু প্লেইন কোন ধারনা না। একটি ফুটবল দল খেলোয়াড়দের একটি তালিকা "আছে" না। এটা খেলোয়াড়দের তালিকা। আপনি বলবেন না "জন ম্যাকফুটবলার কিছুটা খেলোয়াড়ের সাথে যোগ দিয়েছেন"। আপনি বলছেন "জন কিছুটাতে যোগ দিয়েছে"।

আপনি প্রথম বিট সম্পর্কে ভুল আছেন: শব্দটি 'তালিকা' টিপুন, এবং এটি আসলেই স্পষ্ট যে একটি দলের খেলোয়াড় আছে।
যাইহোক, আপনি দ্বিতীয় সঙ্গে মাথা উপর পেরেক আঘাত। আপনি ক্লায়েন্ট কলিং করতে চান না ateam.Players.Add(...)। আপনি তাদের কলিং করতে চান ateam.AddPlayer(...)। এবং আপনার বাস্তবায়ন (সম্ভবত অন্যান্য জিনিসের মধ্যে) Players.Add(...)অভ্যন্তরীণ কল ।

আশা করছি আপনি আপনার বস্তুকে ক্ষমতায়ন করার উদ্দেশ্যে কীভাবে গুরুত্বপূর্ণ encapsulation হয় তা দেখতে পারেন। আপনি অন্য ক্লাস থেকে হস্তক্ষেপের ভয় ছাড়াই প্রতিটি ক্লাসকে তার কাজ ভালভাবে করতে চান।


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

এটা আমার কোড অযথা verbose করে তোলে। আমি এখন my_team.players.Count করতে হবে পরিবর্তে শুধু my_team কল। সৌভাগ্যক্রমে, সি # দিয়ে সূচীগুলিকে স্বচ্ছ করে তুলতে এবং অভ্যন্তরীণ তালিকাগুলির সমস্ত পদ্ধতিগুলিকে এগিয়ে নিয়ে যেতে সূচীগুলিকে সংজ্ঞায়িত করতে পারি ... তবে এটি অনেক কোড! আমি যে কাজ জন্য কি পেতে পারি?

Encapsulation। আপনার ক্লায়েন্টদের FootballTeam ভিতরে কি যায় তা জানা প্রয়োজন। আপনার সমস্ত ক্লায়েন্টদের জানতে, এটি একটি ডাটাবেসের মধ্যে খেলোয়াড়দের তালিকা দেখে দ্বারা প্রয়োগ করা হতে পারে। তারা জানতে হবে না, এবং এই আপনার নকশা উন্নত।

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

ঠিক আছে :) আপনি ফুটবলটাইম বলবেন। যোগ করুন (জন), ফুটবল টিম নয়। তালিকা যোগ করুন (জন)। অভ্যন্তরীণ তালিকা দৃশ্যমান হবে না।


আমার নোংরা গোপন রহস্য: আমি মানুষকে কি বলি তা আমি যত্ন করি না, এবং আমি তা করি। .NET ফ্রেমওয়ার্কটি "XxxxCollection" এর সাথে ছড়িয়ে পড়ে (আমার প্রধান উদাহরণের জন্য UIElementCollection)।

তাই আমাকে বলার অপেক্ষা রাখে না:

team.Players.ByName("Nicolas")

আমি এটা চেয়ে ভাল এটি যখন

team.ByName("Nicolas")

তাছাড়া, আমার প্লেয়ার কলেকশনটি অন্য শ্রেণীর দ্বারা ব্যবহৃত হতে পারে, যেমন "ক্লাবে" কোনও কোড অনুলিপি ছাড়াই।

club.Players.ByName("Nicolas")

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

team.Players.ByName("Nicolas") 

অথবা

team.ByName("Nicolas")

সত্যিই। আপনি কি কোন সন্দেহ আছে? এখন আপনার হয়তো অন্যান্য প্রযুক্তিগত সীমাবদ্ধতার সাথে খেলতে হবে যা আপনাকে আপনার আসল ব্যবহারের ক্ষেত্রে তালিকা <টি> ব্যবহার করতে বাধা দেয়। কিন্তু অস্তিত্ব থাকা উচিত যে একটি সীমাবদ্ধতা যোগ করবেন না। যদি মাইক্রোসফট কেন নথি নথিভুক্ত না করে তবে এটি অবশ্যই কোনও "সেরা অনুশীলন" নয়।


যদিও আমার বেশিরভাগ উত্তর এই রকম জটিল তুলনা করে না তবে আমি এই পরিস্থিতি পরিচালনা করার জন্য আমার পদ্ধতিটি ভাগ করতে চাই। প্রসারিত করে IEnumerable<T>, আপনি আপনার Teamক্লাসকে সমস্ত পদ্ধতি এবং বৈশিষ্ট্যগুলি প্রকাশ্যে প্রকাশ না করেই লিংক ক্যোয়ারী এক্সটেনশনগুলি সমর্থন করতে পারেন List<T>

class Team : IEnumerable<Player>
{
    private readonly List<Player> playerList;

    public Team()
    {
        playerList = new List<Player>();
    }

    public Enumerator GetEnumerator()
    {
        return playerList.GetEnumerator();
    }

    ...
}

class Player
{
    ...
}

শেষ পর্যন্ত, কিছু কিছুতে তালিকা মোড়ানো প্রস্তাব করে:

যে সঠিক উপায়। "অযথাযথভাবে wordy" এই তাকান একটি খারাপ উপায়। যখন আপনি আমার my_team.Players.Count লিখুন তখন এটি একটি সুস্পষ্ট অর্থ my_team.Players.Count । আপনি খেলোয়াড় গণনা করতে চান।

my_team.Count

..আমি কিছুই না। কি গণনা?

একটি দল একটি তালিকা নয় - শুধুমাত্র খেলোয়াড়দের একটি তালিকা ছাড়া গঠিত। একটি দল খেলোয়াড়দের মালিক, সুতরাং খেলোয়াড়দের এটি একটি অংশ হতে হবে (একটি সদস্য)।

আপনি যদি এটি অত্যধিক verbose হচ্ছে সম্পর্কে সত্যিই উদ্বিগ্ন, আপনি সবসময় দলের থেকে বৈশিষ্ট্য প্রকাশ করতে পারেন:

public int PlayerCount {
    get {
        return Players.Count;
    }
}

.. যা হয়ে যায়:

my_team.PlayerCount

এই এখন অর্থ আছে এবং ডিমিটার আইন মেনে চলে।

আপনি কম্পোজিট পুনর্ব্যবহার নীতি অনুসরণ করা বিবেচনা করা উচিত। List<T> থেকে উত্তরাধিকারসূত্রে, আপনি বলছেন একটি দল খেলোয়াড়দের একটি তালিকা এবং এটির প্রয়োজনীয় পদ্ধতি প্রকাশ করছে। এটি ভুল - যেমন আপনি বলেছেন, একটি দল খেলোয়াড়দের তালিকা থেকে বেশি: এটি একটি নাম, পরিচালক, বোর্ড সদস্য, প্রশিক্ষক, চিকিৎসা কর্মী, বেতন ক্যাপ ইত্যাদি। আপনার টিমের ক্লাসে খেলোয়াড়দের একটি তালিকা রয়েছে, আপনি "বলছে একটি দলের খেলোয়াড়দের একটি তালিকা আছে ", কিন্তু এটি অন্যান্য জিনিস থাকতে পারে।


শুধু কারণ আমি মনে করি অন্য উত্তরগুলি একটি ফুটবল দল "আই-এ" List<FootballPlayer>বা " হ্যা-এ" কিনা তা স্পর্শকাতরভাবে অনেক বেশি দূরে চলে যায় List<FootballPlayer>, যা আসলেই লিখিতভাবে এই প্রশ্নের উত্তর দেয় না।

ওপেন মূলত উত্তরাধিকার সূত্রে প্রাপ্ত নির্দেশিকা সম্পর্কে স্পষ্টতা জানায় List<T>:

একটি নির্দেশিকা বলেছেন যে আপনি উত্তরাধিকারী উচিত নয় List<T>। কেন না?

কারণ List<T>কোন ভার্চুয়াল পদ্ধতি আছে। এটি আপনার নিজের কোডের একটি সমস্যা কম, আপনি সাধারণত অপেক্ষাকৃত কম ব্যথা সহ বাস্তবায়নটি স্যুইচ করতে পারেন - তবে এটি একটি সার্বজনীন API এ একটি বড় চুক্তি হতে পারে।

একটি পাবলিক এপিআই কি এবং আমি কেন যত্ন করা উচিত?

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

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

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

আপনি যদি ভবিষ্যতে একটি পাবলিক API যোগ করেন, তবে আপনাকে আপনার বাস্তবায়নের (আপনার List<T>সরাসরি প্রকাশ না করে) আপনার API থেকে বিমূর্ততা বা সম্ভাব্য ভবিষ্যতের ব্যথাগুলি সহ নির্দেশিকাগুলি লঙ্ঘন করতে হবে।

কেন এটা এমনকি কোন ব্যাপার না? একটি তালিকা একটি তালিকা। সম্ভবত কি পরিবর্তন হতে পারে? আমি কি সম্ভবত পরিবর্তন করতে চান?

প্রেক্ষাপটে নির্ভর করে, কিন্তু আমরা FootballTeamএকটি উদাহরণ হিসাবে ব্যবহার করছি - কল্পনা করুন যে আপনি FootballPlayerএটি যোগ করতে পারবেন না যদি এটি দলটিকে টুপি টুপি অতিক্রম করতে দেয়। যোগ করার একটি সম্ভাব্য উপায় এমন কিছু হতে পারে:

 class FootballTeam : List<FootballPlayer> {
     override void Add(FootballPlayer player) {
        if (this.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
          throw new InvalidOperationException("Would exceed salary cap!");
        }
     }
 }

আহ ... কিন্তু আপনি override Addএটি করতে পারবেন না কারণ virtual(কর্মক্ষমতা কারণে)।

আপনি যদি কোনও অ্যাপ্লিকেশানটিতে থাকেন (যা মূলত, আপনি এবং আপনার সমস্ত কলাম একত্রিত হয়) তাহলে আপনি এখন ব্যবহার করতে IList<T>এবং কোনও কম্পাইল ত্রুটিগুলি ঠিক করতে পারেন :

 class FootballTeam : IList<FootballPlayer> {
     private List<FootballPlayer> Players { get; set; }

     override void Add(FootballPlayer player) {
        if (this.Players.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
          throw new InvalidOperationException("Would exceed salary cap!");
        }
     }
     /* boiler plate for rest of IList */
 }

কিন্তু, যদি আপনি প্রকাশ্যে তৃতীয় পক্ষের কাছে প্রকাশ করেছেন তবে আপনি কেবল একটি বিরতি পরিবর্তন করেছেন যা কম্পাইল এবং / অথবা রানটাইম ত্রুটিগুলি সৃষ্টি করবে।

টিএল; ডিআর - নির্দেশিকা পাবলিক APIs জন্য। ব্যক্তিগত API এর জন্য, আপনি যা চান তা করুন।


সর্বোপরি, এটি ব্যবহারযোগ্যতা সঙ্গে আছে। আপনি উত্তরাধিকার ব্যবহার করলে, Team ক্লাসটি আচরণ (পদ্ধতি) প্রকাশ করবে যা বস্তু ম্যানিপুলেশনের জন্য সম্পূর্ণভাবে ডিজাইন করা হয়েছে। উদাহরণস্বরূপ, AsReadOnly() অথবা CopyTo(obj) পদ্ধতিগুলি দলের বস্তুর জন্য কোন ধারনা দেয় না।পরিবর্তে AddRange(items)পদ্ধতিটি সম্ভবত আপনি একটি আরো বর্ণনামূলক AddPlayers(players)পদ্ধতি চাই।

আপনি LINQ ব্যবহার করতে চান, যেমন একটি জেনেরিক ইন্টারফেস বাস্তবায়ন ICollection<T>বা IEnumerable<T>আরো জ্ঞান করতে হবে।

উল্লেখ হিসাবে, রচনা এটি সম্পর্কে যেতে ডান উপায়। শুধু একটি ব্যক্তিগত পরিবর্তনশীল হিসাবে খেলোয়াড়দের একটি তালিকা বাস্তবায়ন।


আমাকে আপনার প্রশ্ন পুনর্লিখন করা যাক। তাই আপনি একটি ভিন্ন দৃষ্টিকোণ থেকে বিষয় দেখতে পারে।

যখন আমাকে ফুটবল দলের প্রতিনিধিত্ব করতে হবে, তখন আমি বুঝতে পারি যে এটি মূলত একটি নাম। ভালো লেগেছে: "ঈগল"

string team = new string();

তারপর আমি বুঝতে পেরেছি দলগুলোর খেলোয়াড়ও আছে।

কেন আমি স্ট্রিং টাইপ প্রসারিত করতে পারি না যাতে এটি খেলোয়াড়দের একটি তালিকাও ধারণ করে?

সমস্যা এন্ট্রি আপনার পয়েন্ট নির্বিচারে হয়। কি একটি দল আছে মনে করার চেষ্টা করুন আছে (বৈশিষ্ট্যাবলী), এটা কি না হয়

আপনি এটি করার পরে, আপনি অন্যান্য ক্লাসের সাথে বৈশিষ্ট্য ভাগ করে দেখতে পারেন। এবং উত্তরাধিকার সম্পর্কে চিন্তা।


বাহ, আপনার পোস্ট প্রশ্ন এবং পয়েন্ট একটি সম্পূর্ণ slee আছে। আপনি মাইক্রোসফ্ট থেকে প্রাপ্ত যুক্তি অধিকাংশ ঠিক পয়েন্ট। চলুন List<T> সম্পর্কে সবকিছু দিয়ে শুরু করি

  • List<T> অত্যন্ত অপ্টিমাইজ করা হয়। তার প্রধান ব্যবহার একটি বস্তুর একটি ব্যক্তিগত সদস্য হিসাবে ব্যবহার করা হয়।
  • মাইক্রোসফ্ট এটি সীল না করে কারণ কখনও কখনও আপনি এমন একটি ক্লাস তৈরি করতে চাইতে পারেন যার একটি বন্ধুত্বপূর্ণ নাম রয়েছে: class MyList<T, TX> : List<CustomObject<T, Something<TX>> { ... } । এখন এটা var list = new MyList<int, string>();
  • CA1002: জেনেরিক তালিকাগুলি প্রকাশ করবেন না : মূলত, আপনি যদি এই অ্যাপ্লিকেশনটিকে একমাত্র বিকাশকারী হিসাবে ব্যবহার করার পরিকল্পনা করেন তবেও ভাল কোডিং অনুশীলনগুলির সাথে বিকাশ করা উপযুক্ত, তাই তারা আপনার এবং দ্বিতীয় প্রকৃতিতে উদ্দীপিত হয়। তালিকাভুক্ত তালিকার জন্য যদি আপনার কোনও ভোক্তা প্রয়োজন হয় তবে আপনাকে এখনও তালিকাভুক্তির জন্য IList<T> হিসাবে তালিকা প্রকাশ করার অনুমতি দেওয়া হয়। এই আপনি পরে ক্লাসে বাস্তবায়ন পরিবর্তন করা যাক।
  • মাইক্রোসফ্ট Collection<T> জেনারিক তৈরি করেছেন কারণ এটি একটি জেনেরিক ধারণা ... নামটি সব বলেছে; এটা শুধু একটি সংগ্রহ। SortedCollection<T> , ObservableCollection<T> , ReadOnlyCollection<T> ইত্যাদি আরও সুনির্দিষ্ট সংস্করণ রয়েছে যা প্রতিটি IList<T> কিন্তু List<T> প্রয়োগ করে না
  • Collection<T> সদস্যদের জন্য (যেমন যোগ করুন, সরান, ইত্যাদি) ওভাররাইড করার অনুমতি দেয় কারণ তারা ভার্চুয়াল। List<T> না।
  • আপনার প্রশ্নের শেষ অংশ স্পট। একটি ফুটবল দল শুধুমাত্র খেলোয়াড়দের একটি তালিকা থেকে বেশি, সুতরাং এটি এমন একটি শ্রেণি হতে হবে যা প্লেয়ারগুলির তালিকা ধারণ করে। রচনা বনাম উত্তরাধিকার চিন্তা করুন । ফুটবল দলের খেলোয়াড়দের তালিকা (একটি রস্টার) রয়েছে, এটি খেলোয়াড়দের তালিকা নয়।

যদি আমি এই কোডটি লিখতাম তবে ক্লাস সম্ভবত এমন কিছু দেখবে:

public class FootballTeam
{
    // Football team rosters are generally 53 total players.
    private readonly List<T> _roster = new List<T>(53);

    public IList<T> Roster
    {
        get { return _roster; }
    }

    // Yes. I used LINQ here. This is so I don't have to worry about
    // _roster.Length vs _roster.Count vs anything else.
    public int PlayerCount
    {
        get { return _roster.Count(); }
    }

    // Any additional members you want to expose/wrap.
}






inheritance