Blog Archives

Builder Pattern


Who does not know the StringBuilder in namespace System.Text?
The purpose of the StringBuilder is to construct a string much faster than using the operator overload “+”. Strings are immutable. Each time you use the overloaded operator, a new object is created. That slows down the creation of the final object. Here is a quick benchmark:

using System;
using System.Diagnostics;
using System.Text;

namespace demo {
  class Program {

    static void Main(string[] args) {
      Stopwatch lStopwatch = new Stopwatch();
      string s = "";
      for (int i = 0; i < 100000; i++) s += "x";
      Console.WriteLine("Operator, elapsed ms: " + lStopwatch.ElapsedMilliseconds);

      StringBuilder lStringBuilder = new StringBuilder();
      for (int i = 0; i < 100000; i++) lStringBuilder.Append("x");
      Console.WriteLine("StringBuilder, elapsed ms: " + lStopwatch.ElapsedMilliseconds);

    } //

  } // class
} // namespace

example output:
Operator, elapsed ms: 3029
StringBuilder, elapsed ms: 1

The StringBuilder supports method chaining. You can shorten your source code and write:

string s = new StringBuilder()

instead of

StringBuilder lStringBuilder = new StringBuilder();
string s = lStringBuilder.ToString();

In general the purpose of a Builder is to separate complex object construction from its representation.

We leave the idea of strings behind and build something entirely different. This time it is not about speed, it is more about avoiding thousands of parameters in constructors and making complexity look a little bit easier. Two weeks ago I was using BMW AG to give an example for an Abstract Factory. Let’s stay loyal to cars and build classes for the production assembly.

using System;

namespace demo {

  public enum eRadio { GPS = 1, MP3 = 2, Screen = 4, Phone = 8 }
  public enum eColor { NotSet = 0, Silver, Red, Blue, White, Black }

  class Program {

    public class Car {
      public readonly eRadio Radio;
      public readonly eColor Color;
      public readonly double Displacement;
      public readonly int Doors;
      public readonly bool Hatchback;
      public readonly bool LeatherSeats;

      internal Car(eRadio xRadio, eColor xColor, double xDisplacement, int xDoors, bool xHatchback, bool xLeatherSeats) {
        Radio = xRadio;
        Color = xColor;
        Displacement = xDisplacement;
        Doors = xDoors;
        Hatchback = xHatchback;
        LeatherSeats = xLeatherSeats;
      } // constructor

    } // class

    public class CarBuilder {

      private eRadio _Radio = 0;
      private eColor _Color = eColor.NotSet;
      private double _Displacement = 0.0;
      private uint _Doors = 1;
      private bool? _Hatchback = null;
      private bool? _LeatherSeats = null;

      internal CarBuilder SetColor(eColor xValue) { _Color = xValue; return this; }
      internal CarBuilder SetDisplacement(double xValue) { _Displacement = xValue; return this; }
      internal CarBuilder SetDoors(uint xValue) { _Doors = xValue; return this; }
      internal CarBuilder SetHatchback(bool xValue) { _Hatchback = xValue; return this; }
      internal CarBuilder SetRadio(eRadio xValue) { _Radio = xValue; return this; }
      internal CarBuilder SetLeatherSeats(bool xValue) { _LeatherSeats = xValue; return this; }
      internal Car Create() {
        if (_Hatchback == null) throw new Exception("Hatchback not set");
        if (_LeatherSeats == null) throw new Exception("LeatherSeats not set");
        if (_Doors < 1 || _Doors > 6) throw new Exception("number of Doors invalid");
        // ... etc.

        return new Car(_Radio, _Color, _Displacement, (int)_Doors, (bool)_Hatchback, (bool)_LeatherSeats);
    } // class

    static void Main(string[] args) {

      Car lCar = new CarBuilder()
        .SetRadio(eRadio.GPS | eRadio.MP3 | eRadio.Screen)

    } // main

  } // class
} // namespace

Reflection (part 6, professional), Emit

Reflection can discover information about objects at runtime and execute against those objects. The namespace System.Reflection.Emit also allows you to build assemblies and create types at runtime. Only a few programmers will come across Emit. You have to be a kind of Rambo sewing yourself while fighting … and definitely not Alice in Wonderland.

Emit generates IL code in memory. The source code for such is quite complex and difficult. We are nearly back to Assembler style. And if you remember well, crashes and difficult debugging were the order of the day. There are tools like the EmitHelper class out there to make Emit easier. I am going to show the fundamentals today, this does not cover tools.

Today’s word list:

Application domains aid security, separating applications from each other and each other’s data. A single process can run several application domains, with the same level of isolation that would exist in separate processes. Running multiple applications within a single process increases server scalability.
Faults in one application domain cannot affect other code running in another application domain.

A module is a portable executable file, such as type.dll or application.exe, consisting of one or more classes and interfaces. There may be multiple namespaces contained in a single module, and a namespace may span multiple modules.
One or more modules deployed as a unit compose an assembly.

The hierarchy is: domain => assemblies => modules => classes => functions


A disassembler for MSIL code.

The first step is to create an executable file from:

using System;
using System.Reflection;

namespace HelloWorld {
    public class Program {
        static void Main(string[] args) {
        } //

        public string Test() {
            return string.Format("DateTime is {0:dd MMM yyyy  HH:mm:ss}", DateTime.Now);
        } //

        public string Test2() {
            return DateTime.UtcNow.ToString();
        } //
        public string Test3() {
            return Assembly.GetExecutingAssembly().ToString();
        } //

        public void Test4() {
            Console.WriteLine("hello world !");
        } //

    } // class
} // namespace

On the windows taskbar, click Start, click All Programs, click Visual Studio, click Visual Studio Tools, and then click Visual Studio Command Prompt.
If you have the Windows SDK installed on your computer: On the taskbar, click Start, click All Programs, click the folder for the Windows SDK, and then click Command Prompt (or CMD Shell).

Change to the right folder and enter “ildasm HelloWorld.exe /”.


In your folder you should see something like this:


Open the file in a text editor and delve into the following sections:

method Test()

  .method public hidebysig instance string 
          Test() cil managed
    // Code size       21 (0x15)
    .maxstack  8
    IL_0000:  ldstr      "DateTime is {0:dd MMM yyyy  HH:mm:ss}"
    IL_0005:  call       valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
    IL_000a:  box        [mscorlib]System.DateTime
    IL_000f:  call       string [mscorlib]System.String::Format(string,
    IL_0014:  ret
  } // end of method Program::Test

method Test3()

  .method public hidebysig instance string 
          Test2() cil managed
    // Code size       20 (0x14)
    .maxstack  1
    .locals init ([0] valuetype [mscorlib]System.DateTime CS$0$0000)
    IL_0000:  call       valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_UtcNow()
    IL_0005:  stloc.0
    IL_0006:  ldloca.s   CS$0$0000
    IL_0008:  constrained. [mscorlib]System.DateTime
    IL_000e:  callvirt   instance string [mscorlib]System.Object::ToString()
    IL_0013:  ret
  } // end of method Program::Test2

method Test3()

  .method public hidebysig instance string 
          Test3() cil managed
    // Code size       11 (0xb)
    .maxstack  8
    IL_0000:  call       class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetExecutingAssembly()
    IL_0005:  callvirt   instance string [mscorlib]System.Object::ToString()
    IL_000a:  ret
  } // end of method Program::Test3

method Test4()

  .method public hidebysig instance void 
          Test4() cil managed
    // Code size       11 (0xb)
    .maxstack  8
    IL_0000:  ldstr      "hello world !"
    IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000a:  ret
  } // end of method Program::Test4

These code sections give you a rough idea of what we are going to code in runtime.
Start a new console project. You have to edit the file “AssemblyInfo.cs”. Add the assembly attribute AllowPartiallyTrustedCallersAttribute. The program won’t run otherwise. We are on a low coding level and Microsoft obviously tries to protect code especially on that level.


using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("oink")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("blablabla")]
[assembly: AssemblyCopyright("Copyright ©  2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AllowPartiallyTrustedCallersAttribute]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("0bf893aa-f3da-49ef-a2dc-a63d8ffc9ead")]

// Version information for an assembly consists of the following four values:
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("")]
[assembly: AssemblyFileVersion("")]

The Print() method is not big, nevertheless you find something unusual here. The keyword __arglist is not official. It has been implemented by Microsoft, but is not documented at all. It is also not well supported in C#. For instance you cannot use a foreach loop. __arglist takes any number of optional arguments like object[]. In our example it does make a big difference to use __arglist. We do not have to create an array and fill it in. This would be much more code in Emit. On the contrary the __arglist algorithm is quite short and comfortable. Follow the link for more __arglist documentation.

public static void Print(string xHeader, __arglist) {
    ArgIterator lIterator = new ArgIterator(__arglist);

    while (lIterator.GetRemainingCount() > 0) {
        TypedReference r = lIterator.GetNextArg();
        object o = TypedReference.ToObject(r);
} //

EmitCode() is the actual code generation part. Let’s call the remaining source code “administration” to simplify the situation.
There are two ways to get the MethodInfo for a property. One is used for DateTime.Now, the other one is used for DateTime.UtcNow .
They can be used equally. I used both ways for demonstration purposes only.
I tried to keep the example simple. You don’t have to study the MSIL to understand the code. Some information about MSIL OpCodes can be found here.

static void EmitCode(ILGenerator xILGenerator) {
    MethodInfo lMethodInfo_Print = typeof(EmitDemo).GetMethod("Print");
    MethodInfo lDateTime_Now = typeof(DateTime).GetProperty("Now").GetGetMethod();
    MethodInfo lFormat = typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) });

    xILGenerator.Emit(OpCodes.Ldstr, "DateTime is {0:dd MMM yyyy  HH:mm:ss}");
    xILGenerator.Emit(OpCodes.Call, lDateTime_Now);
    xILGenerator.Emit(OpCodes.Box, typeof(DateTime));
    xILGenerator.Emit(OpCodes.Call, lFormat);
    xILGenerator.EmitCall(OpCodes.Call, lMethodInfo_Print, new Type[] { });

    xILGenerator.Emit(OpCodes.Ldstr, "This equals UTC: ");
    xILGenerator.Emit(OpCodes.Call, typeof(DateTime).GetMethod("get_UtcNow"));  // compare this with lDateTime_Now (== same, just another demo approach)
    xILGenerator.EmitCall(OpCodes.Call, lMethodInfo_Print, new Type[] { typeof(DateTime) });

    xILGenerator.Emit(OpCodes.Ldstr, "The assembly is: ");
    xILGenerator.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly"));
    xILGenerator.EmitCall(OpCodes.Call, lMethodInfo_Print, new Type[] { typeof(Assembly) });

    xILGenerator.Emit(OpCodes.Ldstr, "Console.WriteLine() is old school.");
    xILGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }));

    xILGenerator.EmitWriteLine("EmitWriteLine() is for lazy programmers.");

} //

Test1_ViaFullAssembly() shows you how to properly initialize and use an assembly. Remember the hierarchy from above: domain => assemblies => modules => classes => functions
The method is build like a chain. Each statement uses the result of the previous one.

public static void Test1_ViaFullAssembly() {
    AssemblyName lAssemblyName = new AssemblyName("MyAssembly");
    AssemblyBuilder lAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(lAssemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder lModuleBuilder = lAssemblyBuilder.DefineDynamicModule("MyModule");
    TypeBuilder lTypeBuilder = lModuleBuilder.DefineType("MyType");
    MethodBuilder lMethodBuilder = lTypeBuilder.DefineMethod("DoSomething", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes);

    Type lType = lTypeBuilder.CreateType();
    lType.GetMethod("DoSomething").Invoke(null, null);

} //

example output:
DateTime is 15 Jan 2014 23:17:30

This equals UTC:
15/01/2014 23:17:30

The assembly is:
MyAssembly, Version=, Culture=neutral, PublicKeyToken=null

Console.WriteLine() is old school.
EmitWriteLine() is for lazy programmers.

You can avoid building a full assembly. DynamicMethod simplifies the dynamic creation of methods. Of course you won’t have any class structure. The method is super-public, it reminds me of VBA modules.

public static void ViaDynamicMethod() {
    DynamicMethod lDynamicMethod = new DynamicMethod("DoSomething", typeof(void), Type.EmptyTypes, typeof(object));
    lDynamicMethod.Invoke(null, null);
} //

example output:
DateTime is 15 Jan 2014 23:17:58

This equals UTC:
15/01/2014 23:17:58

The assembly is:
mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089

Console.WriteLine() is old school.
EmitWriteLine() is for lazy programmers.