Click here to Skip to main content
15,895,606 members
Articles / Programming Languages / Visual Basic 10

Having fun with custom collections!

Rate me:
Please Sign up or sign in to vote.
4.91/5 (71 votes)
14 Oct 2011CPOL44 min read 187.4K   2.9K   121  
Creating custom collections from IEnumerable(T) to IDictionary(T) and everything in between!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TheCult
{
	/// <summary>
	/// A Class representing an organised cult. Each person that enters gets a mark and becomes a cultist.
	/// The organised cult has some sort of politics system allowing some 'favoured people' to enter and get a
	/// high rank right away. This cult also allows replacing of 'bad elements'.
	/// </summary>
	public class OrganisedCult : Cult, IList<Person>
	{

		/// <summary>
		/// Instantiates a new organised cult with no members.
		/// </summary>
		public OrganisedCult()
			: base()
		{
		}

		/// <summary>
		/// Instantiates a new organised cult with members.
		/// </summary>
		/// <param name="people">The people that will join the cult.</param>
		public OrganisedCult(IEnumerable<Person> people)
			: base(people)
		{
		}

		/// <summary>
		/// Searches for the specified person and returns the zero-based index of the first occurrence within the entire cult.
		/// </summary>
		/// <param name="item">The person to locate in the cult. The value can be null for reference types.</param>
		/// <returns>The zero-based index of the first occurrence of the person within the entire cult, if found; otherwise, –1.</returns>
		public int IndexOf(Person item)
		{
			Cultist cultist = base.InnerList.Where(c => c.FullName == item.FullName).FirstOrDefault();
			return base.InnerList.IndexOf(cultist);
		}

		/// <summary>
		/// Checks if a person is eligible to join the cult.
		/// </summary>
		/// <param name="person">The person to check.</param>
		/// <returns>True if a person can join the cult.</returns>
		protected override bool CanJoin(Person person)
		{
			// A person must have a minimum age of 18.
			return base.CanJoin(person) && person.Age >= 18;
		}

		/// <summary>
		/// Inserts a person into the cult at the specified index. This person will get a rank suitable for someone at his position.
		/// All people that are in the cult and have a rank lower than the just inserted person will move down a rank if applicable.
		/// </summary>
		/// <param name="index">The zero-based index at which the person should be inserted.</param>
		/// <param name="item">The person to insert.</param>
		public void Insert(int index, Person item)
		{
			if (item == null)
				throw new ArgumentNullException("Item cannot be nothing.");

			// First check if the person can join.

			if (base.CanJoin(item))
			{
				// Create a cultist and insert it to the inner list.
				Cultist cultist = Cultist.CreateCultist(item, base.GetMark());
				base.InnerList.Insert(index, cultist);

				if (index < 2)
				{
					// If the just inserted person has an index lower than two (someone must like him or this is a hostile takeover!)
					// he is either leader or general. Reset the first three ranks in the inner list.
					base.InnerList[0].Rank = CultRanks.Leader;
					base.InnerList[1].Rank = CultRanks.General;
					base.InnerList[2].Rank = CultRanks.Captain;
				}
				else if (base.InnerList[index + 1] != null && base.InnerList[index + 1].Rank == CultRanks.Captain)
				{
					// If the person above the just inserted person is a captain then the just inserted cultist
					// automatically becomes a captain too.
					cultist.Rank = CultRanks.Captain;
				}
				else
				{
					// If none of the above the just inserted person simply becomes a soldier.
					cultist.Rank = CultRanks.Soldier;
				}

				base.AssignNextCaptainIfNecessary();

			}
		}

		/// <summary>
		/// Gets or sets the item at the specified index.
		/// </summary>
		/// <param name="index">The zero-based index of the person to get or set.</param>
		public Person this[int index]
		{
			get { return base.InnerList[index]; }
			set
			{
				// Cannot use the MyBase.InnerList.Contains, because it contains cultists, not persons.
				if (!this.Contains(value) && this.CanJoin(value))
				{
					// Create a new cultist and replace the old cultist with the new one.
					Cultist cultist = Cultist.CreateCultist(value, base.GetMark());
					cultist.Rank = base.InnerList[index].Rank;
					base.InnerList[index].Rank = CultRanks.None;
					base.InnerList[index] = cultist;
				}
			}
		}

		/// <summary>
		/// Removes the person at the specified index from the cult. New ranks will be assigned as necessary.
		/// </summary>
		/// <param name="index">The zero-based index of the person to remove.</param>
		/// <remarks></remarks>
		public void RemoveAt(int index)
		{
			// Call the MyBase.Remove with the person at the specified index of the inner list.
			// The MyBase.Remove handles recalculations for ranks etc.
			base.Remove(base.InnerList[index]);
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO JUUN Software
Netherlands Netherlands
Sander Rossel is a Microsoft certified professional developer with experience and expertise in .NET and .NET Core (C#, ASP.NET, and Entity Framework), SQL Server, Azure, Azure DevOps, JavaScript, MongoDB, and other technologies.

He is the owner of JUUN Software, a company specializing in custom software. JUUN Software uses modern, but proven technologies, such as .NET Core, Azure and Azure DevOps.

You can't miss his books on Amazon and his free e-books on Syncfusion!

He wrote a JavaScript LINQ library, arrgh.js (works in IE8+, Edge, Firefox, Chrome, and probably everything else).

Check out his prize-winning articles on CodeProject as well!

Comments and Discussions