Typed Collection Class Generator

Copyright © 2002 Kristopher Johnson

Version 1.3 (September 11, 2002)

Contents

Introduction

A strongly-typed or type-safe collection is a class of object that contains other objects, and which guarantees that all contained objects are of a certain type. By using type-safe collections, one can avoid problems related to accidental use of incorrect types, and make the purpose of an object more obvious.

The Typed Collection Class Generator utility can be used to quickly generate type-safe collection and dictionary class definitions in the C# programming language for use with the .NET Framework. This eliminates the "busy work" associated with writing such classes by hand, encouraging developers to do it when it makes sense.

Installation

You must have the .NET Framework installed on your machine before you can install this program. If you do not have the .NET Framework, you can download it from Microsoft.

To install, double-click the TypedCollectionGeneratorSetup.msi file. A Windows Installer setup program will take you though the installation steps.

After installation, there will be a Typed Collection Class Generator group added to your Programs menu. You may want to add this application to the Visual Studio .NET Tools menu for convenient access. Consult the Visual Studio documentation for instructions.

To uninstall the program, open Control Panel and use the Add/Remove Programs application.

How to Use It

To use the utility, do the following:

To Generate a Collection Class

  1. Start the Typed Collection Class Generator Utility from the Programs menu icon or by double-clicking the application icon in Windows Explorer.
  2. Click the Collection tab if that page is not active.
  3. Enter the name of the class of the elements of the collection in the Element Type field. For example, if you have a class called "Frob" and you want to create a collection of Frob instances, enter "Frob" in this field.
  4. Enter the name of the collection class you want to generate in the Collection Class Name field. By default, the utility will fill this field in with the name of your element type with "Collection" appended (for example, "FrobCollection"). You may change this to something else (for example, "FrobList", "Frobs", "BunchOfFrobs", etc.).
  5. By default, documentation comments will be included in the generated class definition. Uncheck the Generate Comments box if you would prefer no comments.
  6. A set of checkboxes lets you control which methods are generated. By default, all are generated, but you can uncheck the boxes for methods that you do not need or which you will develop by hand.
  7. A preview window shows you the code that has been generated. You may examine the code here before proceeding, and adjust the above options if necessary.
  8. Click the Copy to Clipboard to copy the entire generated class definition to the system clipboard.
  9. Paste the definition into a C# source file.
  10. Compile and use the class definition using Visual Studio .NET or another development environment.

To Generate a Dictionary Class

  1. Start the Typed Collection Class Generator Utility from the Programs menu icon or by double-clicking the application icon in Windows Explorer.
  2. Click the Dictionary tab
  3. Enter the name of the class of the elements of the keys of the dictionary in the Key Type field. For example, if you want to use Strings as keys, enter "String" in this field.
  4. Enter the name of the class of the values of the dictionary in the Value Type field. For example, if you want associate strings with Frobs, enter "Frob" in this field.
  5. Enter the name of the dictionary class you want to generate in the Dictionary Class Name field. By default, the utility will fill this field in with the name of your key and value types with "Association" appended (for example, "StringToFrobAssociation"). You may change this to something else (for example, "FrobDictionary", "FrobNames", "NamesOfFrobs", etc.).
  6. By default, documentation comments will be included in the generated class definition. Uncheck the Generate Comments box if you would prefer no comments.
  7. A set of checkboxes lets you control which methods are generated. By default, all are generated, but you can uncheck the boxes for methods that you do not need or which you will develop by hand.
  8. A preview window shows you the code that has been generated. You may examine the code here before proceeding, and adjust the above options if necessary.
  9. Click the Copy to Clipboard to copy the entire generated class definition to the system clipboard.
  10. Paste the definition into a C# source file.
  11. Compile and use the class definition using Visual Studio .NET or another development environment.

Customization and Use

You can add more methods or change the automatically generated methods to suit your needs.

If you want to re-generate the entire class, or just a few methods, you can go through all of the above steps again. You can select individual method definitions in the preview window and copy them by right-clicking or by pressing Ctrl-C.

The generated classes are derived from System.Collections.CollectionBase, or System.Collections.DictionaryBase, so you may use the methods and properties inherited from those classes in addition to the generated methods. Consult the .NET Framework documentation for more information on collection classes.

Code is generated by reading one of two template files in the application directory, CollectionClassTemplate.xml or DictionaryClassTemplate.xml, and then replacing special tokens in the template with the values the user has entered. You can change the format of the generated classes by modifying the template files.

Examples

Collection Example

If you enter "Ship" into the Element Type field and "Fleet" into the Collection Class Name field, and clear the Generate Comments checkbox, the resulting class definition will look like this:

    public class Fleet: System.Collections.CollectionBase
    {
        public Fleet()
        {
            // empty
        }

        public Fleet(Ship[] items)
        {
            this.AddRange(items);
        }

        public Fleet(Fleet items)
        {
            this.AddRange(items);
        }

        public virtual void AddRange(Ship[] items)
        {
            foreach (Ship item in items)
            {
                this.List.Add(item);
            }
        }

        public virtual void AddRange(Fleet items)
        {

            foreach (Ship item in items)
            {
                this.List.Add(item);
            }
        }

        public virtual void Add(Ship value)
        {
            this.List.Add(value);
        }

        public virtual bool Contains(Ship value)
        {
            return this.List.Contains(value);
        }

        public virtual int IndexOf(Ship value)
        {
            return this.List.IndexOf(value);
        }

        public virtual void Insert(int index, Ship value)
        {
            this.List.Insert(index, value);
        }

        public virtual Ship this[int index]
        {
            get
            {
                return (Ship) this.List[index];
            }
            set
            {
                this.List[index] = value;
            }
        }

        public virtual void Remove(Ship value)
        {
            this.List.Remove(value);
        }

        public class Enumerator: System.Collections.IEnumerator
        {
            private System.Collections.IEnumerator wrapped;

            public Enumerator(Fleet collection)
            {
                this.wrapped = ((System.Collections.CollectionBase)collection).GetEnumerator();
            }

            public Ship Current
            {
                get
                {
                    return (Ship) (this.wrapped.Current);
                }
            }

            object System.Collections.IEnumerator.Current
            {
                get
                {
                    return (Ship) (this.wrapped.Current);
                }
            }

            public bool MoveNext()
            {
                return this.wrapped.MoveNext();
            }

            public void Reset()
            {
                this.wrapped.Reset();
            }
        }
        
        public new virtual Fleet.Enumerator GetEnumerator()
        {
            return new Fleet.Enumerator(this);
        }
    }

Dictionary Example

If you enter "Crew" into the Key Type field, "Ship" into the Value Type field, "CrewShipAssignment" into the Dictionary Class Name field, and then clear the Generate Comments checkbox, the resulting class definition will look like this:

    public class CrewShipAssignment: System.Collections.DictionaryBase
    {
        public CrewShipAssignment()
        {
            // empty
        }

        public virtual Ship this[Crew key]
        {
            get
            {
                return (Ship) this.Dictionary[key];
            }
            set
            {
                this.Dictionary[key] = value;
            }
        }

        public virtual void Add(Crew key, Ship value)
        {
            this.Dictionary.Add(key, value);
        }

        public virtual bool Contains(Crew key)
        {
            return this.Dictionary.Contains(key);
        }

        public virtual bool ContainsKey(Crew key)
        {
            return this.Dictionary.Contains(key);
        }

        public virtual bool ContainsValue(Ship value)
        {
            foreach (Ship item in this.Dictionary.Values)
            {
                if (item == value)
                    return true;
            }
            return false;
        }

        public virtual void Remove(Crew key)
        {
            this.Dictionary.Remove(key);
        }

        public virtual System.Collections.ICollection Keys
        {
            get
            {
                return this.Dictionary.Keys;
            }
        }

        public virtual System.Collections.ICollection Values
        {
            get
            {
                return this.Dictionary.Values;
            }
        }
    }

Support

This is free software, so support is limited. Source code is available. Visit http://kristopherjohnson.net/kj/TypedCollectionGenerator or send e-mail to tcg-support@kristopherjohnson.net

License

Typed Collection Class Generator
Copyright © 2002 Kristopher Johnson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Revision History