About this section
Books:
November 6, 2016
Share On Facebook

Object Modeling in the C# Programming Language

Audience

This article is intended for an audience which has a basic understanding of how Microsoft Visual Studio works and how to create a simple project using Visual Studio. Readers do not need to have advanced understanding of C# programming language but some programming experience with the language is helpful in understanding this article; as is, a basic understanding of the .NET framework. Additionally, readers whom have a basic understanding of objects and classes will find it easier to follow than readers who don’t.

Topic & Scope

This article is about object modeling for use in object oriented programming with C#. The scope will be limited to building one object from one model and only one type of modeling methodology. This article does not include visual three dimensional graphical modeling.

Constructs Covered

Object Oriented Programming (OOO), nested types, generics, tuples, and constructors.

Toolkit

The following toolkit was used to create the code represented in this article. Any visual studio and .net framework combination may be used as long as the version of .net includes generics and tuples.

  • Microsoft Visual Studio Enterprise 2015
  • Version 14.0.25431.01 Update 3
  • Microsoft .NET Framework Version 4.6.01586
  • Microsoft Visual C# 2015 00325-70000-18434-AA198

Project

  • Project Difficulty: Easy
  • Project Topic: Advanced
  • Programming Language: C#
  • Project Type: C# Console Application
  • Project References
  • Project references here means referenced assemblies found under the references section of the visual studio project tree.
    • Microsoft.CSharp
    • System

Project Files

For readers that want to jump directly to the models below is the files used in this article:

Model

The object model shall represent the abstract concept of an atom. The atom is represented in many abstract ways, the most common is either a block in the table of elements or a diagram; which in both cases are two dimensional. Three dimensional models are certainly used as well, however, to keep things simple assume a two dimensional model represented by the following definition:

Atom
A self-contained container which encapsulates its components.

To visualize this definition, draw a circle and place inside the circle the representation of the electrons and nucleus where electrons are represented with a circle that denotes an electron path and level around the nucleus. The nucleus shall also be represented as a circle which contains the representation of neutrons and protons. The outer most circle represents the container called an atom. Given this definition, a visual graphical representation is easily drawn. However, building an abstract concept with C# objects require flattening the model in the following way:

  1. The outer most circle become a class container; the atom.
  2. The electron circles become a list of orbit containers; the orbits.
  3. The nucleus circle becomes a class container of: neutron list and proton list.

Model Assumptions

The model is entirely flat, objects exist in the same plane, and no specificity is given to properties of orbits, sub atomic particles, or component interactions. The model is static where no component has associated actions or interactions represented within the model as events. Mass is simplified into periodic lookup table.

Requirements & Goals

Requirements

  1. The model must represent the model definition a close as possible.
  2. Model components must not be assembled in an unnatural way.
    This means; for example, the model should not allow representations of electrons to be placed within the model at locations for which an electron is not expected to occur. Such as the nucleus containing electrons.
  3. The model shall not use inheritance as structure.
  4. Model components must not be useable independently during user model creation. This means individual components cannot be used independently as objects. For example; users of the model should not need to create individual instances of electrons, nucleus, protons and neutrons to assemble an instance of the model. The model should handle creation of components.

Goals

  1. End users of the model should consider it easy to create instances of the model.
  2. Model creation should require three steps or less to create an instance of the model.
  3. Model must create most of its components.

Building The Model

Project Creation & Setup

  1. Using Visual Studio create a new C# console project.
    Give it a name. Name of the project is not important. I named mine CATO. (Console ATomic Object)
    Select a .net framework. I’m using 4.6.1
    Save the project.
  2. When visual studio is done creating the project a blank console application with a main program file, application configuration file, and bunch of references should exist. Clean up the project before building the model.
    Expand the references section and remove unneeded references so that only two references remain. 1. Microsoft.CSharp and 2. System. While this step is not necessary it is considered good practice to remove items known to be unused.
    Open the Program.cs file and remove all of the using statements at the top except for “Systems.Collections.Generic”.
  3. The project is now ready to start the model build.

Create Code Files

  1. Add a new C# (.cs) file to the project and give it the name Atom.cs
    Remove all using statements from the top except “Systems.Collections.Generic”
    Visual Studio doesn’t mark the class as public so add the “public” keyword.
    The class name should look like “public class Atom”.
  2. Add a new C# (.cs) file to the project and give it the name “AtomParameters.cs”.
    Remove all using statements at the top none are necessary in this file.
    Remove the default class definition as the file should only contain the namespace.
    Meaning, remove the automatically generated class named “class AtomParameters” as this file will only contain a NameSpace definition, for later use, to add classes to it.
  3. Add a new C# (.cs ) file to the project and give it the name “Mass.cs”. Remove all using statements except “System” and “System.Collections.Generic” Change the class declaration to “public static class Mass”.

Building Model Objects

Before writing the code to build the model I wanted to take a moment to comment on the order of code writing. Modeling in C# or any programming language is typically an iterative process where object build order (writing order) is smallest independent classes followed by larger dependent objects and model sections.

Code is just text; no requirements exist to write code in any specific order as long as final code content compiles into a runnable program.

However, tools in Visual Studio make it easier to write independent objects first and dependent objects later in the code writing process. Visual Studio’s object tracking, on-the-fly error checking and “intellisense” help to quickly write and catch errors during the writing process.

Writing The Code

  • Open Atom.cs
  • Inside of the “public class Atom{ }”
  • Add two new classes.
    • class Orbit { } //do not use the public keyword
    • class Nucleus { } //do not use the public keyword
  • Inside of “class Orbit { } “
    • Add “class EL { }” //EL for electron, do not use the public keyword here.
    • Inside of “class EL { }” add a public constructor for EL.
    • The class should look like this:
            class  EL {
            public EL()   { }
            }
        
    • Add Orbit class properties.
    • Directly under “class orbit {“ add properties for position and electrons
      public int position {get; set;}
      List<EL> electrons {get; set;}
      
  • Create two constructors for the Orbit class. One to initialize the position and electron properties and another to iterate over the electron collection and set the orbital positions.
        public Orbit()
        {
             this.electrons = new List <EL>();
             this.position = 0;
        }
        public Orbit (int position, int electrons) : this()
        {
    
        }
    
  • The complete Orbit class should now look like the following:
            class Orbit
            {
            public int position { get; set; }
            List<EL> electrons { get; set; }
    
            public Orbit()
                {
                    this.electrons = new List<EL>();
                    this.position = 0;
                }
    
                public Orbit(int position, int electrons) : this()
                {
                         this.position = position;
                         for (int i = 1; i <= electrons; i++)
                         {
                            EL electron = new EL();
                            this.electrons.Add(electron);
                         }
                 }
    
                class EL
                {
                    public EL() {}
                 }
             }
                
  • Inside of “class Neucleus { }
  • Create another class for proton with a public constructor.
    class PR
    {
        public () PR {}
    }
    
  • Create another class for neutron with a public constructor.
    class NU
    {
        public NU(){}
    }
    
  • Add properties and constructors in a similar way to Orbit.
    Directly under “class Nucleus {“ add two properties:
    private List<PR> protons {get; set;}
    private List<NU> neutrons {get; set;}
  • Add two constructors one to initialize the properties and another to iterate the collections of protons and neutrons.
  • The first constructor:
    private Nucleus()
    {
        this.protons = new List<PR>();
        this.neutorns = new List<NU>()
    }
    
  • The second constructor
    public Nucleus(int protons, int neutrons) : this()
    {
        for (int i = 1; i <= protons; i ++)
        {
            PR proton = new PR();
            this.protons.Add(proton);
        }
        for (int i = 1; i <= neutrons; i ++ )
        {
            NU neutron = new NU();
            this.neutrons.Add(neutron);
        }
    }
    
  • At this point a completed Nucleus class should like this:
  • class Nucleus
    {
        private List<PR>protons { get; set; }
        private List<NU>neutrons { get; set; }
        private Nucleus()
        {
            this.protons = new List<PR>();
            this.neutrons = new List<NU>();
        }
    
        public Nucleus(int protons, int neutrons) : this()
        {
            for (int i = 1; i <= protons; i++)
            {
                PR proton = new PR();
                this.protons.Add(proton);
            }
    
            for (int i = 1; i <= neutrons; i++)
            {
                NU neutron = new NU();
                this.neutrons.Add(neutron);
            }
        }
    
       class PR
       {
         public PR(){}
       }
    
       class NU
       {
         public NU(){}
       }
    }
        
  • Complete the Atom model by adding properties and constructors to the Atom class. First other classes for which the Model depends should be completed because the constructors of the Atom class depends on them. The model will need some kind of parameters to use for building out the model so let’s add them next.

  • Open the file AtomParameters.cs. As a reminder, this file should only contain a namespace declaration.

  • Create a class named OrbitalParameter and add properties and constructors:

  •         public class OrbitalParameter
            {
                // Properties
                public int OrbitalPosition  { get;  private set; }
                public int NumberOfElectrons { get; private set; }
                // Constructors
                private OrbitalParameter() { }
                public OrbitalParameter ( int position, int electrons )
                {
                    OrbitalPosition = position;
                    NumberOfElectrons = electrons;
                }
            }
        
  • Create a class named NucleusParameters and add properties and constructors:

  •         public class NucleusParameters
            {
                // Properties
                public int NumberOfProtons {get; private set; }
                public int NumberOfNutrons {get; private set; }
                // Constructors
                private NucleusParameters(){}
                public NucleusParameters ( int protons, int nutrons )
                {
                    NumberOfProtons = protons;
                    NumberOfNutrons = nutrons;
                }
            }
    
  • The completed AtomParameters.cs file should now look like this:
            namespace CATO
            {
                    public class OrbitalParameter
                    {
                        public int OrbitalPosition { get; private set; }
                        public int NumberOfElectrons { get; private set; }
                        private OrbitalParameter() { }
                        public OrbitalParameter(int position, int electrons)
                        {
                            OrbitalPosition = position;
                            NumberOfElectrons = electrons;
                        }
                    }
                    public class NucleusParameters
                    {
                        public int NumberOfProtons { get; private set; }
                        public int NumberOfNutrons { get; private set; }
                        private NucleusParameters() { }
                        public NucleusParameters(int protons, int nutrons)
                        {
                            NumberOfProtons = protons;
                            NumberOfNutrons = nutrons;
                         }
                    }
            }
    
  • Finish the Atom Class:
    Add the properties and constructors to finish the Atom model.
    Add the following properties under “public class Atom {“

  •     // Properties
        private List<Orbit> orbits { get; set; }
        private Nucleus nucleus { get; set; }
        public int AtomicNumber {get; private set; }
        public string Symbol { get; private set; }
        public string Name {get; private set; }
        // Constructors
        private Atom()
        {
            this.orbits = new List<Orbit>();
        }
        public Atom (List<OrbitalParameter> orbitalParams, NucleusParameters neucleusParams) : this()
        {
            foreach (OrbatialParameter oparam in orbitalParams)
            {
                this.orbits.Add(new Orbit(oparam.OrbitalPosition, oparam.NumberOfElectrons));
            }
            this.AtomicNumber = neucleusParams.NumberOfNutrons;
            this.nucleus = new Nucleus(neucleusParams.NumberOfProtons, neucleusParams.NumberOfNutrons);
            this.Symbol = Mass.Elements([this.AtomicNumber].Item2;
            this.Name = Mass.Elements[this.AtomicNumber].Item1;
        }
    

The Mass Class

The model will need a reference point to determine mass properties when the model is built at runtime. A simple Mass class which references mass properties from a periodic table of elements should be sufficient.

Open the Mass.cs file
Under “public static class Masss {“
Add property
public static Dictionary<int,Tuple<string,string>> Elements { get; set; }

Add a constructor next
static class Mass() {}
Initialize the Elements dictionary inside the constructor
Elements = new Dictionary <int, Tuple<string, string>>();

Create dictionary entries from the periodic table of elements. The example below only includes a fragment of the entire Mass class as it is too long to publish here.
CLICK HERE (for Mass.cs) for the full contents.

        Elements.Add(1, new Tuple<string, string>("Hydrogen", "H"));
        Elements.Add(2, new Tuple<string, string>("Helium", "He"));
        Elements.Add(3, new Tuple<string, string>("Lithium", "Li"));
        

The Mass class should look like the following:

        public static class Mass
        {
            public static Dictionary<int,Tuple<string,string>> Elements { get; set; }
        static Mass()
        {
            Elements = new Dictionary<int, Tuple<string, string>>();
            Elements.Add(1, new Tuple<string, string>("Hydrogen", "H"));
            Elements.Add(2, new Tuple<string, string>("Helium","He"));
            Elements.Add(3, new Tuple<string, string>("Lithium", "Li"));
            //NOTE: Remainder of elements left out to keep this example short.
            //      enter the remaining elements in the same pattern or simply copy
            //      the Mass.cs code entirely from CLICK HERE.
         }
     }
}
            

Model Implementation

The implementation of the model is straight forward. The program.cs file contains a “static void Main” method where the implement should be placed. The implementation shows how to use the model to create an instance of the Atom model.

The code below does not take any arguments at runtime and produces no input our output. To see the Atom model created at run time simply add a break point in Visual studio then build and run the program. Using the debugging tools, observe that the model was created and contains the Atom components. (expand the Atom in the debugger and drill down to see the components)

  • Open program.cs
  • Inside of the method body create the parameters which build out the final model.
  • The main method: static void Main(string[] args){ implementation code goes here}

The entire Main method should look like the following:

static void Main(string[] args)
{
    List<OrbitalParameter> orbitalParameters = new List<OrbitalParameter>();
    orbitalParameters.Add(new OrbitalParameter(4, 3));
    orbitalParameters.Add(new OrbitalParameter(3, 6));
    orbitalParameters.Add(new OrbitalParameter(1, 9));
    NucleusParameters nucleusParameters = new NucleusParameters(2, 4);
    var atom = new Atom(orbitalParameters, nucleusParameters);
}
        

Congratulations ! You are Done.

General Notes on Constructs

Object Oriented Programming

Object oriented programming often abbreviated using (OOO) has different definitions depending on the programming language and authors of software. In C# everything is an object and this article represents only one OOO pattern among many. The Atom model pattern may not fit other software types, such as business models which use hierarchy, inheritance and polymorphism resulting in a different OOO pattern.

Nested Types

Nested types are useful for reducing the amount of object creation code required and reduces the complexity for the end user of the model. Consider the following example of object creation in C#:

Proton p1 = new Proton();
Proton p2 = new Proton();
Nucleus n = new Nucleus();
Electron el1 = new Electron();
Electron el2 = new Electron();
Orbit orbit1 = new Orbit();
Orbit orbit2 = new Orbit();
Atom atom = new Atom (p1,p2,n,el1,el2,orbit1,orbit2);

The pattern above, would be cumbersome for end users to implement as it would require creating many lines of code to build the model. This article demonstrates the use of nested types to avoid verbose patterns and how to use nested types to self-generate objects for which the model depends.

Nested types are also useful for hiding components which are not intended for use by the end user. The Atom model does not does not directly expose any of the atomic components other than name, number and symbol.

The atom model, as written, does not allow for interaction between instances of components. This means two instances of the Atom class cannot interact. To clarify; naturally atoms interact exchanging electrons forming isotopes or molecules, but in this model, electrons are not exposed; therefore, two instances of the atom model cannot exchange electrons. The model works well for representing individual atoms and succeeds at meeting the intended definition but building representations of molecules is omitted due to the model requirements.

Generics

The model uses two generic types from the System.Collections.Generic library; list and dictionary. The components of the model are collected with a list and the mass is collected with a dictionary. Observe the dictionary takes an integer as the key and a Tuple as the entry value.

Tuples

The Mass classes uses tuples as the value referenced by an integer key. This allows the model to easily access any value contained in the tuple for any given key. The Mass class is an example of how to build a multivalued dictionary. The use of tuples is not required to build a multivalued dictionary as any object that may contain multiple values (or properties) may be used.

Constructors

The use of constructors in this model demonstrate how to use multiple constructors for a given class and how to designate constructor order. The first constructor instantiates objects the class needs and the second constructor takes parameters. Call order is defined by the keyword “this()”. The effect of using “this()” is to indicate the constructor must first call the base constructor of the class and then proceed to build the remaining objects for which it contains.

Next Steps

The model as defined has limitations. Consider changing the model to allow interactions between atomic components. Additionally, consider adding additional classes to allow combining of the Atom model to form a molecular model.

Try breaking the model structure apart to avoid the use of nested types and discover a different way to model an Atom. Or perhaps; remove the use of Generics in favor of C# structs, arrays, or other objects avaiable in the framework.

Performance is also impacted by the object model used. Consider, removing iterative bulding of objects (foreach) in favor of other methods of object creation in C#. To clarify, when the creation of atoms numbers in the millions using generics with "foreach" may become very slow so, consider avoiding foreach and generics in favor of other methods.

Make the model useful and build a sofware application with it. The model, with the given requirements is fairly limited and was only intended to get you started with modeling.

REFERENCES

  • Nested Types
    https://msdn.microsoft.com/en-us/library/ms173120.aspx
  • Tuples
    https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx
  • Generics
    https://msdn.microsoft.com/en-us/library/512aeb7t.aspx
  • Microsoft Object Oriented Programming
    https://msdn.microsoft.com/en-us/library/mt656686.aspx
  • Project Files
    Project files are listed at top of article.