Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » Enumerations » Downloads
 
Add your own
alternative version

Enum Generitized

, 12 May 2007 CPOL
Using Generics to make a different kind of enumeration: easy to comment, and supports many types.
using System;
using System.Reflection;
using System.Collections.Specialized;
using System.Data;

namespace ThreeOaks.EnumGeneritized
{
	/// <summary>
	/// A class to inherit from to create DateTime like enumerations.
	/// Having a public constant for each value will help developers in assigning DateTime values.
	/// </summary>
	[Serializable()]
	public abstract class DateTimeEnumClass
	{
		/// <summary>
		/// Constructor that must be called to set internal array of values.
		/// </summary>
		public DateTimeEnumClass()
		{
            Initialize();
		}

        /// <summary>
        /// Constructor where the value may be set.
        /// </summary>
        /// <param name="setValue">value to set to.</param>
        public DateTimeEnumClass(DateTime setValue)
        {
            Initialize();
            this.Value = setValue;
        }

        /// <summary>
        /// Set internal arrays and dictionaries to hold values.
        /// </summary>
        private void Initialize()
        {
            //get the name of the class
            Type t = this.GetType();

            //check if have _values loaded
            if (_values.Contains(t.FullName) == false)
            {

                //use reflection to get values

                FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Static);
                int numFields = fields.Length;
                DateTime[] values = new DateTime[numFields];
                string[] names = new string[numFields];
                for (int i = 0; i < numFields; i++)
                {
                    if (fields[i].IsInitOnly == true && fields[i].FieldType == _value.GetType())
                    {
                        //Need to check if value already loaded
                        DateTime addValue = (DateTime)fields[i].GetValue(null);
                        for (int j = 0; j < values.Length; j++)
                        {
                            if ((DateTime)values[j] == addValue)
                            {
                                throw new NotSupportedException("Value with duplicate names not supported.");
                            } //no dups
                        } //cycle through them
                        values[i] = addValue; //(DateTime)fields[i].GetValue(null) ;
                        names[i] = fields[i].Name;
                    } //get readonly 
                    if (fields[i].IsInitOnly == true && fields[i].FieldType != _value.GetType())
                    {
                        throw new ArrayTypeMismatchException("A constant with a different type from the value type has been declared. Look for " + fields[i].FieldType.Name);
                    } //check for mismatch in data type
                } //loop through Public fields


                //values should now be loaded so put in static list
                _values.Add(t.FullName, values);
                _names.Add(t.FullName, names);
            }
        }

        /// <summary>
        /// Using key collection to hold an array by child type.
        /// This way the values only need to load once.
        /// </summary>
        private static HybridDictionary _values = new HybridDictionary();
        /// <summary>
        /// Holds the names of the values per child type.
        /// This way the value names only need to load once.
        /// </summary>
        private static HybridDictionary _names = new HybridDictionary();

        /// <summary>
        /// Holds the current value.
        /// </summary>
		private DateTime _value  ;

        /// <summary>
        /// Holds if value for instance has been set
        /// </summary>
        private bool _isValueSet = false;
        /// <summary>
        /// Indicates if the enum's value has been set.
        /// </summary>
        public bool IsValueSet
        {
            get { return _isValueSet; }
        }


		/// <summary>
		/// The enum value.
		/// </summary>
		public DateTime Value
		{
            get
            {
                if (_isValueSet == true)
                {
                    return _value;
                }
                else
                {
                    throw new ApplicationException("Value not set");
                }
            }
            set
            {

                _isValueSet = false;
                //Don't let null in
                //DateTime can't be null
                //if (value == null)
                //{
                //    throw new NoNullAllowedException("Not allowed to assign null value.");
                //}
                //else
                //{
                //get the array to work with from the collection
                //Type t = this.GetType();
                DateTime[] values = (DateTime[])_values[this.GetType().FullName];
                foreach (DateTime v in values)
                {

                    if (v == value)
                    {
                        _value = value;

                        _isValueSet = true;
                        return;
                    }
                }
                if (_isValueSet == false)
                {
                    throw new ArgumentOutOfRangeException(value.ToString() + " not found in enumeration.");
                }
                //}
            }
		}

		/// <summary>
		/// Returns the name of the assigned value.
		/// </summary>
		public string Name
		{
			get {return GetNameForValue(_value);}
		}

		/// <summary>
		/// Returns a clone of the available values.
		/// </summary>
		public DateTime[] GetValues()
		{  //want to return copy
			DateTime[] values = (DateTime[])_values[this.GetType().FullName];
			return (DateTime[])values.Clone();
		}
		
		/// <summary>
		/// Returns a clone of the available values.
		/// </summary>
		public string[] GetNames()
		{ 	
			string[] names = (string[])_names[this.GetType().FullName];
			return (string[])names.Clone();
			
		}
		
		/// <summary>
		/// Two dimensional string array with first dimension as the "row",
		/// the second dimension containing the "column".
		/// Column 0 is name, Column 1 is the value
		/// </summary>
		/// <returns>two dimensional string array</returns>
		public string[,] GetNamedValues()
		{
			DateTime[] values = (DateTime[])_values[this.GetType().FullName];
			string[] names = (string[])_names[this.GetType().FullName];
			//create two dimensional array
			string[,] namedValues = new string[values.Length,2];
			
			for (int i =0;i<values.Length ; i++ )
			{
					namedValues[i,0] = (string)names[i] ;
					namedValues[i,1] = ((DateTime)values[i]).ToString("G");
			}


			return namedValues;

		}

		/// <summary>
		/// For the supplied value, returns corresponding Name
		/// Returns zero length string if value not found.
		/// </summary>
		public string GetNameForValue(DateTime forValue)
		{
			
			DateTime[] values = (DateTime[])_values[this.GetType().FullName];
			string[] names = (string[])_names[this.GetType().FullName];
			
			string name = "";
			for (int i =0;i<values.Length ; i++ )
			{
				if (forValue == (DateTime)values[i])
				{
					name =(string)names[i] ;
				}
				
				
			}

			return name;

		}
		/// <summary>
		/// Returns a DataTable with two columns,
		/// the first for the Name
		/// the second for the Value
		/// </summary>
		public DataTable GetNamedValuesTable()
		{
			DateTime[] values = (DateTime[])_values[this.GetType().FullName];
			string[] names = (string[])_names[this.GetType().FullName];
			//create table
			DataTable dt = new DataTable();
			DataColumn dc = new DataColumn();
			DataRow dr;
			dc.DataType = System.Type.GetType("System.String");
			dc.ColumnName = "Name";
			dc.AutoIncrement = false;
			dc.Caption = "Name";
			dc.ReadOnly = true;
			dc.Unique = true;
			dt.Columns.Add(dc);

			dc = new DataColumn();
			dc.DataType = System.Type.GetType("System.DateTime");
			dc.ColumnName = "Value";
			dc.AutoIncrement = false;
			dc.Caption = "Value";
			dc.ReadOnly = true;
			dc.Unique = true;
			dt.Columns.Add(dc);
			
			for (int i =0;i<values.Length ; i++ )
			{
				dr = dt.NewRow();
				dr["Name"] = (string)names[i] ;
				dr["Value"] = (DateTime)values[i];
				dt.Rows.Add(dr);
			}
			dt.AcceptChanges();
			return dt;

		}

	} //DateTimeEnumClass

}

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)

Share

About the Author

Tim Schwallie
Team Leader
United States United States
A biography in this little spot...sure.
I've worked at GTE HawaiianTel. I've worked at Nuclear Plants. I've worked at Abbott Labs. I've consulted to Ameritech Cellular. I've consulted to Zurich North America. I've consulted to International Truck and Engine. Right now, I've consulted to Wachovia Securities to help with various projects. I've been to SHCDirect and now at Cision.
 
During this time, I've used all kinds of tools of the trade. Keeping it to the more familier tools, I've used VB3 to VB.NET, ASP to ASP/JAVASCRIPT/XML to ASP.NET. Currently, I'm developing with C# and ASP.NET. I built reports in Access, Excel, Crystal Reports, and Business Objects (including the Universes and ETLS). Been a DBA on SQL Server 4.2 to 2000 and a DBA for Oracle. I've built OLTP databases and DataMarts. Heck, I've even done Documentum. I've been lucky to have created software for the single user to thousands of concurrent users.
 
I consider myself fortunate to have met many different people and worked in many environments. It's through these experiences I've learned the most.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 12 May 2007
Article Copyright 2007 by Tim Schwallie
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid