Polymorphism In C#: Treating Different Types of Objects as if they were the Same Type

Polymorphism In C#: Treating Different Types of Objects as if they were the Same Type

In this post I present the two types of polymorphism supported by C#: Static and Dynamic Polymorphism. C#’s language features including inheritance, abstract base classes, interfaces, virtual methods, method overriding, method overloading, operator overloading, and generics, offers you a rich pallate from which you can design and create robust application architectures that support the SOLID design principles and allow you to think polymorphically.

 

Don’t Feel Like Reading? Watch the Video Instead!

Introduction to Methods

Introduction to Methods

What Is A Method?

A method is a block of code this is accessible by name. All statements executed within a C# program run within the context of a method. Every C# program needs, at the very least, one method named Main().  (The name of the method is “Main” but I append the parentheses to the name to make it clear I’m talking about a method.) The following code represents a complete C# program:
using System;

public class MethodDemo { 
  public static void Main(){
    Console.WriteLine("The Main() method is the program's \"Entry Point\"");
  }
}
The name of the class is MethodDemo. This class is also an application because it contains a Main() method. When the MethodDemo class is loaded into the .NET Runtime VM, control is passed to the Main() method and it calls the Console.WriteLine() method to write the indicated string to the console. Here’s the results of running the program.

Figure 1 – Results of Running the MethodDemo Program

It’s good practice to keep Main() methods short and sweet. This rule is often broken in C# programming textbooks for the sake of demonstration.

Main() Methods Can Be Confusing

The confusing thing about the Main() method is that it’s static, meaning only one Main() method exists for the MethodDemo type. When I first learned Java, (yes, I meant to type Java!) I really struggled to make sense of having the main() (lower case main() in Java) located in a class definition. I was used to C and C++, where methods could exist outside of classes, but it finally clicked after I pressed the “I Believe” button about a thousand times. The trick for me was to think in terms of programs as being a collections of objects that interact with each other. I then developed the habit of creating a separate application class I usually call “MainApp” and put the Main() method there. Let me make a slight alteration to the code:
using System;

public class MethodDemo {
  public static void WritePithyStatements() { 
    Console.WriteLine("Here's a pithy statement!"); 
  } 
  public static void Main(){
    Console.WriteLine("The Main() method is the program's \"Entry Point\"");
    WritePithyStatements(); } 
}
I’ve added another static method named WritePithyStatements(). When the program loads, the Main() method executes and makes a call to Console.WriteLine() as before. It then calls the WritePithyStatements() method, which in turn makes a call to Console.WriteLine(). Here’s the results of running this program:

Figure 2 – Another Static Method

Constructor Methods

Let’s add another type of method to the mix. Take a look at the following code:
using System;

public class MethodDemo { 
  public MethodDemo(){
    MethodDemo.WritePithyStatements(); 
    Console.WriteLine("Instance of type " + this.GetType() + " created."); 
  } 

  public static void WritePithyStatements(){
    Console.WriteLine("Here's a pithy statement!"); 
  } 

  public static void Main(){
   Console.WriteLine("The Main() method is the program's \"Entry Point\""); 
   MethodDemo md1 = new MethodDemo(); 
  } 
}
In this example I have added a special method called a constructor. A constructor method takes the same name as the class within which it is defined. Notice that it has no return type, not even void. Note that to call the static WritePithyStatements() method from the constructor, you must do so via the classname like so:
MethodDemo.WritePithyStatements();
A common mistake made by novice programmers, myself included back in the day, is to mistakenly do something like this:
public void MethodDemo(){
 MethodDemo.WritePithyStatements(); 
 Console.WriteLine("Instance of type " + this.GetType() + " created."); 
 }
Note — this may look like a constructor, but it’s not. Fortunately, the C# compiler will let you know you’re making a mistake with the following error:
MethodDemo.cs(6,14): error CS0542: 'MethodDemo': member names cannot be the same as their enclosing
type MethodDemo.cs(3,14): (Location of symbol related to previous error)

Instance Methods

Methods can be static, which you’ve seen above, or non-static. Non-static methods are referred to as instance methods. Let me change the static WritePithyStatements() to be non-static and have you examine the results. Here’s the code.
using System;

public class MethodDemo {
  public MethodDemo(){ 
    WritePithyStatements(); 
    Console.WriteLine("Instance of type " + this.GetType() + " created."); 
  } 

  public void WritePithyStatements(){    
    Console.WriteLine("Here's a pithy statement!"); 
  } 

  public static void Main(){ 
    Console.WriteLine("The Main() method is the program's \"Entry Point\""); 
    MethodDemo md1 = new MethodDemo(); 
    md1.WritePithyStatements();
  } 
}
Can you spot the changes? Notice that you can now call WritePithyStatements() directly from the MethodDemo() constructor. You no longer need to access it via the class name. To call WritePithyStatements() in the Main() method requires accessing it via an instance of MethodDemo. That is, since WritePithyStatements() is now a non-static, instance method, you must first create an object of type MethodDemo and call the method via the object reference, which in this example is named md1. Here’s the results of running this version of the program:

Figure 4 – Calling the Non-Static WritePithyStatements() Method

Returning Values From Methods

Methods, other than the constructor, that simply execute a series of logically related statements and then exit are usually defined with the return type void. That is, they return nothing. If the method does some sort of processing and produces a result, you can specify a return type as is shown in the following code:
using System; 

public class MethodDemo { 
  public MethodDemo(){ 
   WritePithyStatements(); 
   Console.WriteLine("Instance of type " + this.GetType() + " created."); 
 } 

 public void WritePithyStatements(){     
   Console.WriteLine("Here's a pithy statement!"); 
 } 

 public int CalculateSum(){ 
   return ((100*(100+1))/2 ); 
}

 public static void Main(){ 
   Console.WriteLine("The Main() method is the program's \"Entry Point\""); 
   MethodDemo md1 = new MethodDemo(); 
   md1.WritePithyStatements(); 
   Console.WriteLine(md1.CalculateSum());
 } 
}
In this example I have added a method named CalculateSum() which returns an integer value. This is indicated by the int return type. The CalculateSum() method calculates the sum of the integers 1 – 100.  The return keyword is used to return the results of the calculation. Note that because CalculateSum() is an instance method, it must be called via an object reference. Also note that anywhere you can use an integer value, you can call a method that returns an integer value. In the example above, the call to md1.CalculateSum() is evaluated first and will return 5050. This value is then passed to the Console.WriteLine() method, which has been overloaded to handle various argument types. (I’ll cover method arguments in another post.) Here’s the results of running this program:

Figure 5 – Calling a Method that Returns a Value

Passing Arguments To Methods

The CalculateSum() method is pretty boring in its current state. To make the method more useful you can define one or more method parameters that represent data that can be “passed” to the method for processing. In the example below I have modified the CalculateSum() method to take an integer argument named “n”.
using System;

public class MethodDemo {
 
  public MethodDemo(){ 
    WritePithyStatements(); 
    Console.WriteLine("Instance of type " + this.GetType() + " created."); 
  } 

  public void WritePithyStatements(){    
    Console.WriteLine("Here's a pithy statement!"); 
  } 

  public int CalculateSum(int n){ 
    if(n<=0) return 0; 
    return ((n*(n+1))/2 ); 
  } 

  public static void Main(){ 
    Console.WriteLine("The Main() method is the program's \"Entry Point\""); 
    MethodDemo md1 = new MethodDemo(); 
    md1.WritePithyStatements(); 
    Console.WriteLine(md1.CalculateSum(100)); 
    Console.WriteLine(md1.CalculateSum(1)); 
    for(int i=1; i<100; i++){  
      Console.Write(md1.CalculateSum(i) + ", "); 
    } 
  } 
}
Figure 6 shows the results of running this program.

Figure 6 – Calling CalculateSum() with Integer Arguments

         
C# Programming – Static Fields/Properties vs. Instance Fields/Properties

C# Programming – Static Fields/Properties vs. Instance Fields/Properties

Classes and structures can contain, among other types of members, fields and properties. In this post I’ll focus on field and property members and explain the difference between instance fields/properties and static fields/properties. Before reading further here’s a short video on the topic:

The Purpose of Fields and Properties

Fields are used to store object state data, and properties are used to set and query object state data. An instance field stores state data for individual objects, that is, every object of a particular type will have its very own copy of any and all instance fields defined for that class or structure type. A static field stores state data for all instances of the type. In other words, a static field’s value is shared by all instances of the type. Let’s take a look at an example.
using System;

public class Employee {
  //Instance Fields 
  private string _firstName; 
  private string _middleName; 

  //Instance Properties 
  public string FirstName {
    get {return _firstName;} 
    set {_firstName = value;} 
  } 

  public string MiddleName {
    get {return _middleName;}
    set {_middleName = value;}
  } 

  public string LastName {
    get;
    set;
  }

  //Static Properties 
  public static int Count {
    get; 
    private set; 
  } 

 //Constructors 
 public Employee(string firstName, string middleName, string lastName){
   _firstName = firstName; 
   _middleName = middleName; 
   LastName = lastName; 
   Employee.Count++; 
 } 

 public Employee():this("John", "J", "Doe"){}

 //Overridden Object Methods 
 public override string ToString(){
   return _firstName + " " + _middleName + " " + LastName; 
 } 
}
Referring to the Employee class – I’ve defined two private fields _firstName and _middleName. These explicit field definitions are used as backing fields for the FirstName and MiddleName public properties, as you can clearly see from the code. If you use fields in this manner, there’s no need to explicitly declare them. Simply use Auto-Implemented properties as I’ve done with the LastName property. As their name implies, auto-Implemented properties automatically create the backing field behind the scenes. This reduces the amount of boilerplate code you need to write.  I’ve mixed the two styles in this example for demonstration purposes. The Count property is a static, class-wide property declared with the help of the static keyword. I increment this value whenever an employee object is created. Note that you must access static properties via the class name. Lastly, in this example I have overridden the Object.ToString() method.  To demonstrate this code I’ll need another class that implements a Main() method.
using System;

public class MainApp {
  public static void Main(){
   Employee e1 = new Employee();
   Employee e2 = new Employee("Rick", "W", "Miller");
   Console.WriteLine(e1); 
   Console.WriteLine(e2); 
   Console.WriteLine(Employee.Count); 
  }
}
Referring to the MainApp class – I create two instances of Employee testing both versions of the constructor. I then write their values to the console and then, with the help of the static Employee.Count property, I write the number of employee objects created. Figure 1 shows the results of running this program.

Figure 1 – Results of Running MainApp

 
Creating Complex Solutions in Visual Studio – Part II: Logging

Creating Complex Solutions in Visual Studio – Part II: Logging

Complex applications need more than simple Console.WriteLine() statements sprinkled about the code to record application state for debugging and diagnostics purposes. That’s a job for logging packages. In this post, I’ll explain how to integrate logging into a complex Visual Studio solution based on a multi-layered application architecture. I’ll show you how to use the Visual Studio package manager to download and install the NLog package and how to configure NLog to write logs to an asynchronous log file. The reference architecture I’ll be using is shown in figure 1.

Figure 1 – Multi-Layered Application Architecture w/Logging

Referring to figure 1 – I will install the NLog logging package in the Infrastructure layer and make logging services available via two classes: ApplicationBase, which can be extended as required, and StaticLogger, which can be used on an ad hoc basis anywhere within the application. Before I get started, here’s a video that explains everything:

Install NLog NuGet Package in the InfrastructureLayer Project

Launch Visual Studio and open the EmployeeTraining solution you created in Part I of this series. Select the InfrastructureLayer project and from the main menu select Tools -> NuGet Package Manager -> Package Manager Console. This will open the Package Manager Console as is shown in figure 2.

Figure 2 – Package Manager Console

At the Default project dropdown select the InfrastructureLayer project. At the prompt type Find-Package to list packages available via your configured package source. Figure 3 shows the packages available on my system.

Figure 3 – Find-Package Command Showing Available NuGet Packages

The package you want to install is NLog. Be sure you’ve selected the InfrastructureLayer project and at the prompt type Install-Package NLog. If NLog installs successfully your Package Manager Console will look something like figure 4.

Figure 4 – Install-Package NLog Results

You may close the Package Manager Console. Inspect the InfrastructureLayer project to ensure a packages.config file has been added and that the NLog library reference appears in the project References as is shown in figure 5.

Figure 5 -InfrastructureLayer Project after Installing NLog Package

Install NLog.config File Template

It’s a royal pain in the butt to hand-jam an XML configuration file, so I recommend you install the NLog.config file template. From the main menu select Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution… Click the Browse tab and in the Search text box type NLog. Your Visual Studio window will look something like figure 6.

Figure 6 – NLog.config File Template Package is Second from the Top

Select NLog.config from the list of packages and to the right check the box next to the InfrastructureLayer project as is shown in figure 7.

Figure 7 – Installing NLog.config File Template

Click the Install button to install the package then click OK on the confirmation pop-up window. This will add two files to the project: NLog.config and NLog.xsd. Inspect the InfrastructureLayer project to ensure those two files are there. Now it’s time to configure NLog.

Configure NLog

Before NLog can write logs anywhere you’ll need to add at least one Target and one Rule to the NLog.config file. I will also show you how to use a Variable.  In the <targets> section add the following code:
<target xsi:type="AsyncWrapper" name="asyncFile">
    <target xsi:type="File" name="logfile" fileName="${var:logDirectory}"/>
 </target>
This target specifies a file target named “logfile”. The filename is specified by a variable named “logDirectory” which is defined in the variables section like so:
<variable name="logDirectory" value="${basedir}/logs/${shortdate}"/>
Note that the logDirectory variable itself uses two build-in NLog variables “basedir” and “shortdate”. To access a variable’s value use ${ }. Note that there are actually two targets defined. One is the logfile and the other is an AsyncWrapper named “asyncFile”. For more information on the purpose of the AsyncWrapper target consult the NLog wiki. Now we need a rule. In the <rules> section add the following code:
<logger name="*" minlevel="Trace" writeTo="asyncFile" />
This rule will cause all loggers to write Trace level messages and above to the asyncFile target defined in the <targets> section. When you’ve completed your edits, save and close the NLog.config file.    

Implement Logging

It’s time now to actually implement logging. I like to make logging available throughout an application in two ways:
  1. Create a base class that makes logging available to derived classes
  2. Create a static class that can be used on an ad hoc basis in cases where the base class cannot be extended or where doing so would be an awkward construct.
I will name the base class “ApplicationBase” and the static class “StaticLogger”. I will locate both classes in the InfrastructureLayer project in a folder named “Common”.  Let’s start with ApplicationBase. here’s the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;

namespace InfrastructureLayer.Common
{
   public class ApplicationBase
    {
      protected Logger Log { get; private set; }

      protected ApplicationBase(Type declaringType)
        {
            Log = LogManager.GetLogger(declaringType.FullName);
        }
    }
}
Note the highlighted code. The namespace is InfrastructureLayer.Common because this class resided in the Common folder within the InfrastructureLayer project. I’ve defined a protected property named Log which is of type Logger. The constructor takes a Type argument, which is used to name the logger. Let’s now define the StaticLogger class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;

namespace InfrastructureLayer.Common
{
    public static class StaticLogger
    {
        public static void LogInfo(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Info(text);
        }

        public static void LogWarn(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Warn(text);
        }

        public static void LogDebug(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Debug(text);
        }

        public static void LogTrace(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Trace(text);
        }

        public static void LogError(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Error(text);
        }

        public static void LogFatal(Type declaringType, string text)
        {
            LogManager.GetLogger(declaringType.FullName).Fatal(text);
        }
    }
}
Note the names of the static methods in StaticLogger correspond to the log level methods on a Logger. OK, let’s take a look at each of the classes in action.

EmployeeVO Class

To demonstrate the use of both the ApplicationBase and the StaticLogger classes, I’ll create two versions of a class named EmployeeVO. The first version will extend ApplicationBase. The second version will use the StaticLogger class. Create a new folder in the InfrastructureLayer project and name it VO. Add the EmployeeVO class to the VO folder. Here’s EmployeeVO version1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using InfrastructureLayer.Common;

namespace InfrastructureLayer.VO
{
    public class EmployeeVO : ApplicationBase
    {
        public EmployeeVO() : base(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
        {
            Log.Debug("Using ApplicationBase.Log Property");
        }
    }
}
This version of EmployeeVO extends the ApplicationBase class. The EmployeeVO constructor passed the DeclaringType to the base constructor through constructor chaining. The ApplicationBase.Log property is used in the constructor body to call the Logger.Debug() method. To test this version of the EmployeeVO class go to the PresentationLayer project and open the Form1.cs file. Right click to view the code and and edit it to look like the following code snippet:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using InfrastructureLayer.VO;

namespace EmployeeTraining
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            EmployeeVO vo = new EmployeeVO();
        }
    }
}
You only need to add two lines of code which are highlighted above. All you’re doing is creating an instant of EmployeeVO because the logging takes place in that class’s constructor. When you made the changes save the file and run the solution. The log file will be written to the “…/debug/logs/” directory of the PresentationLayer project folder if you named your PresentationLayer project as suggested at the beginning of this post, otherwise, the logs directory will be located in the working directory of the executable project. Here’s what the log output looks like after running the solution:
2017-07-09 08:23:30.7420|DEBUG|InfrastructureLayer.VO.EmployeeVO|Using ApplicationBase.Log Property
Your dates will be difference, of course. Here’s EmployeeVO version 2 using the StaticLogger class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using InfrastructureLayer.Common;

namespace InfrastructureLayer.VO
{
    public class EmployeeVO
    {
        public EmployeeVO() 
        {
            StaticLogger.LogDebug(this.GetType(), "This class has a serious problem!");
        }
    }
}
There’s no need to change the code in Form1.cs. Once you’ve made these changes to the EmployeeVO class run the solution again. Here’s the log output from this example:
2017-07-09 08:27:10.8038|DEBUG|InfrastructureLayer.VO.EmployeeVO|Using StaticLogger.LogDebug() method
 

Summary

Consolidating logging to the InfrastructureLayer project saves you from having to install NLog in every project in complex Visual Studio solutions. You can create as many logger rules and targets as required. I hope you found this post helpful. Happy coding!
Creating Complex Solutions in Visual Studio – Part I: Setup

Creating Complex Solutions in Visual Studio – Part I: Setup

To create anything other than trivial programs you’ll need to structure and organize your Visual Studio solution in a way that enables separation of concerns. In this post I’ll show you how to create a complex Visual Studio solution consisting of multiple sub-projects that reflects the organization of a multi-layered application architecture. Before I get started, take a look at the following video.

Reference Application Architecture

Figure 1 shows the reference architecture I’ll use to structure the Visual Studio solution:

Figure 1 – Multi-Layered Application Architecture

  • Infrastructure Layer – Contains Value Objects (VOs), (A.K.A. Data Transfer Objects (DTOs), which are lightweight objects used to pass data between application layers. I show the Infrastructure Layer spanning all the other layers because they all have a dependency upon the Infrastructure Layer. In addition to VOs, the Infrastructure Layer will contain any common code, objects, or functionality required by all the other layers.
  • Data Access Layer – Contains Data Access Objects (DAOs) which are used to interact with the database/data store.
  • Business Object Layer – Contains Business Objects (BOs), which provide a logical grouping of related functionality. Transaction control resides in this layer as well.
  • Presentation Layer – This is generally the User Interface (UI) and can be implemented in many different technologies including ASP.NET, Windows Presentation Foundation (WPF), Windows Forms, MVC, etc.
All these application layers represent separate sub-projects in a complex Visual Studio solution. The Infrastructure, Data Access, and Business Object layers are library projects meaning they will be set to compile to .dll files, whereas the Presentation Layer will be an executable or a web application.

Create the Solution

Start by creating the Presentation Layer project. Launch Visual Studio. In this post I’ll be using Visual Studio 2015. Select File -> New -> Project. In the New Project window select Windows Forms Application. Set the project’s Name, Location, and Solution Name. For the project’s name I’ve entered “PresentationLayer”. I’ve set the location to a Projects folder located on my desktop, and I’ve set the Solution Name to “EmployeeTraining”. See figure 2.

Figure 2 – Creating PresentationLayer Project

Give everything a second check and click OK. This will create the project in the designated folder and open the solution as is shown in figure 3.

Figure 3 – Solution Created

At this point you can build and run the solution. Right click on the EmployeeTraining solution and select Build Solution, or click the Start button located to the right of the green triangle in the center of the menu.

Add Remaining Sub-Projects

You must now add the remaining sub-projects to the EmployeeTraining solution. I’ll start with the InfrastructureLayer project. Right click on the EmployeeTraining solution and click Add -> New Project… This will open the Add New Project window. Select Class Library from the list of available project types and name it InfrastructureLayer as is shown in figure 4.

Figure 4 – Adding the InfrastructureLayer Project

Click the OK button. Your solution will now look like figure 5.

Figure 5 – InfrastructureLayer Project Added to Solution

Now repeat the previous steps and add the DataAccessLayer and BusinessObjectLayer projects. Figure 6 shows how the solution looks after all sub-projects have been added to the solution.

Figure 6 – All Sub-Projects Added to the Solution

Note that all the class library projects have a default “Class1.cs” file. We’ll deal with these in a later video, but the short story is they can either be renamed or deleted. Next thing you need to do is to set project dependencies.

Setting Project Dependencies

Right-click on the EmployeeTraining solution and select Properties from the pop-up menu. This will open the Solution Property Pages window as is shown in figure 7.

Figure 7 – InfrastructureLayer Project Dependencies

From the Projects dropdown select the InfrastructureLayer project. Note that all three projects listed in the Depends on section should remain unchecked. Next select the DataAccessLayer project from the Projects dropdown as is shown in figure 8.

Figure 8 – DataAccessLayer Project Dependencies

Note that the DataAccessLayer project has one dependency on the InfrastructureLayer project. This means that before the DataAccessLayer project can compile and build, the InfrastructureLayer project must have compiled and built successfully. Next, select the BusinessObjectLayer project from the Projects dropdown. Set the dependencies as shown in figure 9.

Figure 9 – BusinessObjectLayer Project Dependencies

Lastly, set the project dependencies for the PresentationLayer project as is shown in figure 10.

Figure 10 – PresentationLayer Project Dependencies

Next, you’ll need to add references to each sub-project.

Add Project References to Sub-Projects

All the sub-projects will depend on the InfrastructureLayer project, so you’ll need to add a reference to that project in each of the other sub-projects (PresentationLayer, BusinessObjectLayer, and DataAccessLayer). Let’s begin with the PresentationLayer. Right-click the References section under the PresentationLayer project and click Add Reference… This will open the Reference Manager window for the PresentationLayer project as shown in figure 11.

Figure 11 – Adding References to PresentationLayer Project

Referring to figure 11 – Note that the PresentationLayer project will need references to the InfrastructureLayer and BusinessObjectLayer projects. Repeat this step for the BusinessObjectLayer and DataAccessLayer projects. the BusinessObjectLayer project will depend on both the InfrastructureLayer and the DataAccessLayer projects, so it will need references to those projects. The DataAccessLayer project will depend solely upon the InfrastructureLayer project. (These will not be the only references you’ll need to add, but for now it’s a start.) You can again build the solution. You haven’t added any functionality, other than what the Windows Form project (PresentationLayer) gave you out-of-the-box, but you’ve set yourself up to be able to better manage complex projects based on multi-layer architectures. In Part II of this series I’ll show you how to add logging capability to the InfrastructureLayer project using NLog. I hope you’ve found this post helpful.