/*
*Derivation constraints state the ascendancy of a type parameter.
*Interface constraints are interfaces that are implemented by the type parameter.
*Value type constraints restrict a type parameter to a value type.
*Reference type constraints restrict a type parameter to a reference type.
*Constructor constraints stipulate that the type parameter has a default or parameterless constructor.
*/
Generics
Represents a generic collection of key/value pairs. The enumerator returns the values in the order assigned.
//http://visualizer.codeplex.com/license
//Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace Redwerb.BizArk.Core.Collections
{
/// <summary>
/// Represents a generic collection of key/value pairs. The enumerator returns the values in the order assigned.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public class HashList<TKey, TValue>
: IList<TValue>
{
#region Fields and Properties
private Dictionary<TKey, int> mDictionary = new Dictionary<TKey, int>();
private List<TValue> mList = new List<TValue>();
/// <summary>
/// Gets or sets the value for the given key.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public TValue this[TKey key]
{
get { return GetValue(key); }
set
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
SetValue(key, value);
}
}
/// <summary>
/// Gets or sets the value at the designated index.
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public TValue this[int index]
{
get { return mList[index]; }
set
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
mList[index] = value;
}
}
/// <summary>
/// Gets the number of items in the list.
/// </summary>
public int Count
{
get { return mList.Count; }
}
private bool mIsReadOnly = false;
/// <summary>
/// Gets a value that determines if the list if readonly.
/// </summary>
public bool IsReadOnly
{
get { return mIsReadOnly; }
protected set { mIsReadOnly = value; }
}
#endregion
#region Methods
/// <summary>
/// Adds the value to the list.
/// </summary>
/// <param name="index"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public void Insert(int index, TKey key, TValue value)
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
if (mDictionary.ContainsKey(key)) throw new ArgumentException("Key already exists in the collection.");
mList.Insert(index, value);
foreach (var item in mDictionary.ToArray())
{
if (item.Value >= index)
mDictionary[item.Key] = item.Value + 1;
}
mDictionary.Add(key, index);
}
/// <summary>
/// Adds the value to the list.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Add(TKey key, TValue value)
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
if (mDictionary.ContainsKey(key)) throw new ArgumentException("Key already exists in the collection.");
SetValue(key, value);
}
/// <summary>
/// Removes the item from the list.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Remove(TKey key)
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
if (!mDictionary.ContainsKey(key)) return false;
var i = mDictionary[key];
mDictionary.Remove(key);
mList.RemoveAt(i);
foreach (var item in mDictionary.ToArray())
{
if (item.Value > i)
mDictionary[item.Key] = item.Value - 1;
}
return true;
}
/// <summary>
/// Removes the item from the list.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public bool Remove(TValue value)
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
var key = GetKey(value);
return Remove(key);
}
/// <summary>
/// Removes the value at the designated index.
/// </summary>
/// <param name="index"></param>
public void RemoveAt(int index)
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
var key = GetKeyFromIndex(index);
Remove(key);
}
/// <summary>
/// Removes all the items from the list.
/// </summary>
public void Clear()
{
if (mIsReadOnly) throw new InvalidOperationException("The list is readonly.");
mDictionary.Clear();
mList.Clear();
}
/// <summary>
/// Gets the value from the list.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
protected TValue GetValue(TKey key)
{
var i = mDictionary[key];
return mList[i];
}
/// <summary>
/// Gets the value from the list. If the key is not in the list, returns the default value.
/// </summary>
/// <param name="key"></param>
/// <param name="dflt">Default value to return if the key does not exist.</param>
/// <returns></returns>
public TValue GetValue(TKey key, TValue dflt)
{
TValue value;
if (TryGetValue(key, out value)) return value;
return dflt;
}
/// <summary>
/// Gets the value from the list. Returns true if the value exists, otherwise false.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool TryGetValue(TKey key, out TValue value)
{
if (!mDictionary.ContainsKey(key))
{
value = default(TValue);
return false;
}
var i = mDictionary[key];
value = mList[i];
return true;
}
/// <summary>
/// Sets the value in the list.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
protected int SetValue(TKey key, TValue value)
{
int i;
if (mDictionary.ContainsKey(key))
{
i = mDictionary[key];
mList[i] = value;
}
else
{
mList.Add(value);
i = mList.Count - 1;
mDictionary.Add(key, i);
}
return i;
}
/// <summary>
/// Determines if the key is in the list.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool ContainsKey(TKey key)
{
return mDictionary.ContainsKey(key);
}
/// <summary>
/// Determines if the item is in the list.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(TValue item)
{
return mList.Contains(item);
}
/// <summary>
/// Gets the index of the given item.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public int IndexOf(TKey key)
{
if (!mDictionary.ContainsKey(key)) return -1;
return mDictionary[key];
}
/// <summary>
/// Gets the index of the given item.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public int IndexOf(TValue value)
{
return mList.IndexOf(value);
}
/// <summary>
/// Gets the key based on the value.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public TKey GetKey(TValue value)
{
var i = mList.IndexOf(value);
if (i < 0) throw new ArgumentException("Value not found in the collection.");
foreach (var keyVal in mDictionary)
{
if (keyVal.Value == i)
return keyVal.Key;
}
// This should never happen, but just in case.
throw new InvalidOperationException("The key was not found in the collection.");
}
/// <summary>
/// Gets the key based on the index.
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public TKey GetKeyFromIndex(int index)
{
foreach (var item in mDictionary)
if (item.Value == index) return item.Key;
throw new ArgumentOutOfRangeException("The index was not found in the dictionary.");
}
/// <summary>
/// Returns the collection of keys.
/// </summary>
public ICollection<TKey> Keys
{
get { return mDictionary.Keys; }
}
/// <summary>
/// Gets the enumerator for the list.
/// </summary>
/// <returns></returns>
public IEnumerator<TValue> GetEnumerator()
{
return mList.GetEnumerator();
}
/// <summary>
/// Gets the enumerator for the list.
/// </summary>
/// <returns></returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Gets an array of the values.
/// </summary>
/// <returns></returns>
public TValue[] ToArray()
{
return mList.ToArray();
}
/// <summary>
/// Copies the values to an array.
/// </summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
void ICollection<TValue>.CopyTo(TValue[] array, int arrayIndex)
{
mList.CopyTo(array, arrayIndex);
}
#endregion
#region Unsupported IList methods
void IList<TValue>.Insert(int index, TValue item)
{
throw new NotSupportedException("Cannot insert values without the key.");
}
void ICollection<TValue>.Add(TValue item)
{
throw new NotSupportedException("Cannot add values without the key.");
}
#endregion
}
}
Generic collection class
using System;
using System.Collections.Generic;
public class Bag<T> {
private List<T> items = new List<T>();
public void Add(T item) {
items.Add(item);
}
public T Remove() {
T item = default(T);
if (items.Count != 0) {
Random r = new Random();
int num = r.Next(0, items.Count);
item = items[num];
items.RemoveAt(num);
}
return item;
}
public T[] RemoveAll() {
T[] i = items.ToArray();
items.Clear();
return i;
}
}
public class MainClass {
public static void Main(string[] args) {
Bag<string> bag = new Bag<string>();
bag.Add("D");
bag.Add("B");
bag.Add("G");
bag.Add("M");
bag.Add("N");
bag.Add("I");
Console.WriteLine("Item 1 = {0}", bag.Remove());
Console.WriteLine("Item 2 = {0}", bag.Remove());
Console.WriteLine("Item 3 = {0}", bag.Remove());
Console.WriteLine("Item 4 = {0}", bag.Remove());
string[] s = bag.RemoveAll();
}
}
Add object in a hierarchy into a generic Collection
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
public class Chicken : Animal {
public void LayEgg() {
Console.WriteLine("{0} Animal.", name);
}
public Chicken(string newName)
: base(newName) {
}
}
public class Cow : Animal {
public void Milk() {
Console.WriteLine("{0} cow.", name);
}
public Cow(string newName)
: base(newName) {
}
}
public abstract class Animal {
protected string name;
public string Name {
get {
return name;
}
set {
name = value;
}
}
public Animal() {
name = "animal";
}
public Animal(string newName) {
name = newName;
}
public void Feed() {
Console.WriteLine("{0} is feeding.", name);
}
}
class Program {
static void Main(string[] args) {
Collection<Animal> animalCollection = new Collection<Animal>();
animalCollection.Add(new Cow("A"));
animalCollection.Add(new Chicken("B"));
foreach (Animal myAnimal in animalCollection) {
myAnimal.Feed();
}
}
}
Sort by Name
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
public class Employee : System.IComparable {
private int _id;
private string _name;
private string _rating;
private static SortOrder _order;
public enum SortOrder {
Ascending = 0,
Descending = 1
}
public Employee(int id, string name)
: this(id, name, "Other") {
}
public Employee(int id, string name, string rating) {
this._id = id;
this._name = name;
this._rating = rating;
}
public int Id {
get { return this._id; }
set { this._id = value; }
}
public string Name {
get { return this._name; }
set { this._name = value; }
}
public string Rating {
get { return this._rating; }
set { this._rating = value; }
}
public static SortOrder Order {
get { return _order; }
set { _order = value; }
}
public override bool Equals(Object obj) {
bool retVal = false;
if (obj != null) {
Employee custObj = (Employee)obj;
if ((custObj.Id == this.Id) &&
(custObj.Name.Equals(this.Name) &&
(custObj.Rating.Equals(this.Rating))))
retVal = true;
}
return retVal;
}
public override string ToString() {
return this._id + ": " + this._name;
}
public int CompareTo(Object obj) {
switch (_order) {
case SortOrder.Ascending:
return this.Name.CompareTo(((Employee)obj).Name);
case SortOrder.Descending:
return (((Employee)obj).Name).CompareTo(this.Name);
default:
return this.Name.CompareTo(((Employee)obj).Name);
}
}
}
public class CollectionTest {
public static void Main() {
List<Employee> collCustList = new List<Employee>();
collCustList.Add(new Employee(99, "H", "P"));
collCustList.Add(new Employee(77, "B", "G"));
collCustList.Add(new Employee(55, "B", "G"));
collCustList.Add(new Employee(88, "B", "P"));
collCustList.Add(new Employee(11, "L", "O"));
foreach (Employee cust in collCustList)
Console.Out.WriteLine(cust);
Employee.Order = Employee.SortOrder.Ascending;
collCustList.Sort(delegate(Employee cust1, Employee cust2) {
return Comparer<Employee>.Default.Compare(cust1, cust2);
});
foreach (Employee cust in collCustList)
Console.Out.WriteLine(cust);
Employee.Order = Employee.SortOrder.Descending;
collCustList.Sort(delegate(Employee cust1, Employee cust2) {
return Comparer<Employee>.Default.Compare(cust1, cust2);
});
foreach (Employee cust in collCustList)
Console.Out.WriteLine(cust);
}
}
Add Collection Items with IComparable interface implementation
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
public class Customer : System.IComparable {
private int _id;
private string _name;
private string _rating;
private static SortOrder _order;
public enum SortOrder {
Ascending = 0,
Descending = 1
}
public Customer(int id, string name)
: this(id, name, "Other") {
}
public Customer(int id, string name, string rating) {
this._id = id;
this._name = name;
this._rating = rating;
}
public int Id {
get { return this._id; }
set { this._id = value; }
}
public string Name {
get { return this._name; }
set { this._name = value; }
}
public string Rating {
get { return this._rating; }
set { this._rating = value; }
}
public static SortOrder Order {
get { return _order; }
set { _order = value; }
}
public override bool Equals(Object obj) {
bool retVal = false;
if (obj != null) {
Customer custObj = (Customer)obj;
if ((custObj.Id == this.Id) &&
(custObj.Name.Equals(this.Name) &&
(custObj.Rating.Equals(this.Rating))))
retVal = true;
}
return retVal;
}
public override string ToString() {
return this._id + ": " + this._name;
}
public int CompareTo(Object obj) {
switch (_order) {
case SortOrder.Ascending:
return this.Name.CompareTo(((Customer)obj).Name);
case SortOrder.Descending:
return (((Customer)obj).Name).CompareTo(this.Name);
default:
return this.Name.CompareTo(((Customer)obj).Name);
}
}
}
public class CollectionTest {
public static void Main() {
Collection<Customer> custColl = new Collection<Customer>();
custColl.Add(new Customer(1, "S"));
custColl.Add(new Customer(2, "K"));
custColl.Add(new Customer(3, "T"));
custColl.Insert(1, new Customer(4, "Inserted Employee"));
custColl[3] = new Customer(9, "F");
foreach (Customer cust in custColl)
Console.Out.WriteLine(cust);
}
}
Add user-defined object to generic Collection
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
class Team {
private string name;
public Team(string name) {
this.name = name;
}
public override string ToString() {
return name;
}
}
class Program {
static void Main(string[] args) {
Collection<Team> teams = new Collection<Team>();
teams.Add(new Team("Ferrari"));
teams.Add(new Team("Williams-BMW"));
teams.Add(new Team("Bar-Honda"));
teams.Add(new Team("McLaren-Mercedes"));
foreach (Team t in teams) {
Console.WriteLine(t);
}
}
}