October 11, 2005

Singleton Implementation in c#

At http://csharpindepth.com/Articles/General/Singleton.aspx can be found a full description of the different c# singletons and their advantages and disadvantages
Here is the fast thread safe one:
#region Fast Thread Safe Singleton Implementation

static $ClassName$()
{}

private $ClassName$()
{}

private static readonly $ClassName$ instance= new $ClassName$();

public static $ClassName$ Instance
{
  get { return instance; }
}

#endregion
as a snippet:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Keywords>
        <Keyword>SimpleSingleton</Keyword>
      </Keywords>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>SimpleSingleton</Title>
      <Author>R Bovill</Author>
      <Description>Make a threadsafe singleton class</Description>
      <HelpUrl>
      </HelpUrl>
      <Shortcut>SimpleSingleton</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="false">
          <ID>ClassName</ID>
          <ToolTip>
          </ToolTip>
          <Default>
          </Default>
          <Function>ClassName()</Function>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[
        #region Fast Thread Safe Singleton Implementation
        
        static $ClassName$()
        {}

        private $ClassName$()
        {}

        private static readonly $ClassName$ instance = new $ClassName$();

        public static $ClassName$ Instance
        {
            get
            {
                return instance;
            }
        }

        #endregion Fast Thread Safe Singleton Implementation
        ]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>
Full lazy implementation as a snippet:
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Keywords>
        <Keyword>Full Lazy Singleton</Keyword>
      </Keywords>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>FullLazySingleton</Title>
      <Author>Microsoft</Author>
      <Description>Make a threadsafe singleton class</Description>
      <HelpUrl>
      </HelpUrl>
      <Shortcut>FullLazySingleton</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="false">
          <ID>ClassName</ID>
          <ToolTip>
          </ToolTip>
          <Default>
          </Default>
          <Function>ClassName()</Function>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[
    #region Thread Safe Lazy Singleton Implementation
    
    private $ClassName$()
    {
    }

    public static $ClassName$ Instance
    {
        get
        {
            return Nested.instance;
        }
    }
    
    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly $ClassName$ instance = new $ClassName$();
    }


    #endregion Thread Safe Lazy Singleton Implementation
]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

October 5, 2005

Pattern/Sample To Parse Xml Using XmlReader

Heres some sample text that shows how to parse some Xml with XmlTextReader I am trying to demonstrate parsing of attributes, empty nodes and layered nodes all in one go that’s why its quite complex

   #region ReadIBVDescriptor Method

  private const string ELEMENT_NAME = "IBVDescriptor";

  // Parse some xml fragment 
  // <IBVDescriptor>...</IBVDescriptor>
  // On exit the XmlReader is pointing to the 
  // node immediately following
  // the end element node ('</IBVDescriptor>')
  public static IBVDescriptor ReadIBVDescriptor(
    XmlReader xmlReader)
  {
    // Move to the next start element
    // ('<IBVDescriptor>') if not already there
    MoveTo(xmlReader, XmlNodeType.Element);
    _Assert((xmlReader.Name == IBVDescriptor_ELEMENT_NAME)
      &&amp; (xmlReader.NodeType == XmlNodeType.Element));
    int startDepth = xmlReader.Depth;
    bool elementIsEmpty = xmlReader.IsEmptyElement;
    // PARSE ATTRIBUTES of the descriptor root node
    string name = xmlReader.GetAttribute("Name");
    string provider = xmlReader.GetAttribute("Provider");
    string tmp = xmlReader.GetAttribute("RunningStatus");
    // To parse an attribute directly into an 'enum' value
    // use the following code pattern
    Service.RunningStatuses runningStatus =
      (Service.RunningStatuses)Enum.Parse(
      typeof(Service.RunningStatuses), tmp);
    byte type = byte.Parse(xmlReader.GetAttribute("Type"));
  
    IBVDescriptor descriptor = new IBVDescriptor(
      name, provider, runningStatus, type);
     if (!elementIsEmpty)
    {
      xmlReader.Read();
       bool endOfDesc = false;
      DataService ds = null;
      string val;
      while (true)
      {
        // look for the end of the main parent element node
        endOfDesc = (xmlReader.Name == ELEMENT_NAME) &&
          (xmlReader.NodeType == XmlNodeType.EndElement);
        if (endOfDesc)
          break;

        // PARSE ELEMENT NODES
        // Begin Element Processing ''
        if (xmlReader.NodeType == XmlNodeType.Element)
        {
          // Do something with the node
          switch (xmlReader.Name)
          {
            case "DataService":
              _Assert(ReferenceEquals(ds, null));
              string id = xmlReader.
                GetAttribute("DataServiceId");
              ds = new DataService(id);
              xmlReader.Read();
              break;

            case "Reserved":
              // Interpret an element node. In this
              // case we assume it cannot be empty
              _Assert(!xmlReader.IsEmptyElement);
              val = xmlReader.ReadElementString();
              ds.Reserved = val;
              break;
            case "FieldParity":
              // Can read in an entire Xml
              // fragment as a string if required
              val = xmlReader.ReadOuterXml();
              descriptor.FieldParity = val;
              break;
            case "Authorisation":
              // Can devolve complex xml fragments to
other routines
              Authorisation val =
XmlHelper.ReadAuthorisation(xmlReader);
                descriptor.Authorisation = val;
                break;
            default: // Whitespace etc.
              //TODO_NODE(xmlReader);
              // Can use Skip() to ignore unhandled XML
              XmlHelper.Skip(xmlReader);
                break ;
          }
        }
        else
        {
          // End Element Processing '</xxx>'
          if (xmlReader.NodeType == XmlNodeType.EndElement)
          {
            if (xmlReader.Name == "DataService")
            {
              _Assert(!ReferenceEquals(ds, null));
              descriptor.AddDataService(ds);
              ds = null;
            }
          }
          xmlReader.Read();
        }
      }
  
      // Use xmlReader.Depth to ensure we are still
      _Assert(xmlReader.Depth == startDepth);
      _Assert((xmlReader.Name == IELEMENT_NAME) &&amp;
        (xmlReader.NodeType == XmlNodeType.EndElement));
      xmlReader.Read();
    }
    return descriptor;
  }

  #endregion ReadIBVDescriptor Method

  // Helper method to skip the next node.
  // 'XmlTextReader.Skip()' does not handle
  // empty element nodes, ie.
  // those of format '<xxx />'
  public static void Skip(XmlReader xmlReader)
  {
    if (xmlReader.IsEmptyElement)
      xmlReader.Read();
    else
      xmlReader.Skip();    
  }

  public static void MoveTo(
          XmlReader xmlReader, XmlNodeType nodeType)
  {
     while (!xmlReader.EOF && 
            (xmlReader.NodeType != nodeType) )
     {
        xmlReader.Read() ;
     }
  }

Using XmlTextReader With a String

Pattern for Using XmlTextReader with a string. This is useful for testing your Xml Parsing

//Create the XML fragment to be parsed.
string xmlFrag =
  "<Transport Label=\"TS1\" TransportId=\"1\" 
OrigNetworkId=\"1\" >" + " <Metadata>" + " <Id>c98dced0-1efc-48c3-aa37-cae5141c6615</Id>" + " <ProfileDescription>Test TS</ProfileDescription>" + " </Metadata>" + "</Transport>"; // Create a XmlTextReader that will read from an Xml string XmlTextReader xmlReader = new XmlTextReader( xmlFrag, XmlNodeType.Element, new XmlParserContext(null, new XmlNamespaceManager(
new NameTable()), null, XmlSpace.Default)); // <= XXX // Can set how to handle whitespace here! //xmlReader.WhitespaceHandling = WhitespaceHandling.All; Transport transport = XmlProcessor.ReadTransport(xmlReader) ; //Close the reader. xmlReader.Close();

A longer version for the creating the XmlTextReader. Replace the line XXX with this

//Create the XmlNamespaceManager.
NameTable nt = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
//Create the XmlParserContext.
XmlParserContext context = new XmlParserContext(
null, nsmgr, null, XmlSpace.Default); //Create the reader, tell it the fragment represents
an Xml Element type of node XmlTextReader xmlReader = new XmlTextReader(
xmlFrag, XmlNodeType.Element, context);

August 30, 2005

c# Array Append Pattern

Pattern to append one array to the end of another in c#
public static class ArrayAppender
{
  public static TYPE[] Append(this TYPE[] b1, TYPE[] b2)
  {
    TYPE[] newArray = new TYPE[b1.Length + b2.Length];
    Array.Copy(b1, 0, newArray, 0, b1.Length);
    Array.Copy(b2, 0, newArray, b1.Length, b2.Length);
    return newArray;
  }
}

internal class ArrayAppendTester
{
  public void Test()
  {
    int[] intArray1 = new int[4] { 42, 7, 6, 3 };
    int[] intArray2 = new int[7] { 1, 2, 3, 4, 5, 6, 7};

    int[] newArray = ArrayAppender.Append(intArray1, intArray2);
    int[] newArray2 = intArray1.Append(intArray2);
  }
}

Format of an c# Indexer

Indexer format:

class XXX 
{
// RETURN_TYPE is type that is returned by the indexer
// INDEX_TYPE is the indexer look up type
public RETURN_TYPE this[INDEX_TYPE index] 
{
  get{return ...;}
  set{... = value;}
}
Note that their can be multiple indexers
public RETURN_TYPE this[INDEX_TYPE_1 index1, ..., INDEX_TYPE_N indexN] 
{
  get{ ... }
  set{ ... }
}

Equals Operator Pattern

Equality in C#

Pattern for implementing required operators to support '==', '!=', 'Equals()' and 'GetHashCode()' for a new reference or value type. Need to implement these methods together.

For REFERENCE types
public override bool Equals(object rhs)
{
    if (rhs == null) // this cannot be null
        return false;

    if (object.ReferenceEquals(this, rhs)
        return true;

    // Check for null values and compare run-time types.
    if (this.GetType() != rhs.GetType())
         return false;

    return CompareFields(rhs as XXX);
}

private bool CompareFields(XXX p)
{ // Field by field comparison
  return (this.field1 == this.field2) && ...; 
}


public override int GetHashCode()
{   // Aim to get a unique number from the objects state 
    int tmp = ((int)(field1 << 16) + field2) ... ;
    return tmp;
}

In general it is not recommended to override the '==' and '!=' operators for reference types. They should only be overriden for immutable types. However here is a suitable implementation:
public static bool operator ==(XXX obj1, XXX obj2)
{
// IF obj1 is null
//  so obj2 must be for equality
// ELSE obj1 is not null,  
//  compare it with obj2 using above Equals() operator
    if (ReferenceEquals(obj1, null))        
        return ReferenceEquals(obj2, null); 
    else                                    
        return obj1.Equals(obj2);           
}

public static bool operator !=(XXX obj1, XXX obj2)
{
    return !(obj1 == obj2);
}
For VALUE types
public override bool Equals(object rhs)
{
    if (rhs == null) // this cannot be null
        return false;

    return Equals(rhs as XXX);
}

public override bool Equals(XXX rhs)
{
    return CompareFields(rhs);
}


private bool CompareFields(XXX p)
{ // Field by field comparison
  return (this.field1 == this.field2) && ...; 
}

public override int GetHashCode()
{   // Aim to get a unique number from the objects state 
    int tmp = ((int)(field1 << 16) + field2) ... ;

    return tmp;
}

// For VALUE types
public static bool operator ==(XXX lhs, XXX rhs)
{
    bool res = lhs.Equals(rhs);
    return res;
}

public static bool operator !=(XXX lhs, XXX rhs)
{ 
    return !(lhs==rhs); 
}

Here is a Unit Test To Test the Equals operator Create 'x', 'y' and 'z' that are the same and an object 'a' that is not

TestEqualsOperator()
{
  // Ensure all the XXX objects have the same constructor 
  // except the one called 'different'
  XXX a = new XXX(...);
  XXX x = new XXX(...);
  XXX y = new XXX(...);
  XXX z = new XXX(...);
  XXX different = new XXX(...); 

  Debug.Assert(x.Equals(x) == true);
  Debug.Assert(x.Equals(y) == y.Equals(x));
  Debug.Assert((x.Equals(y) && y.Equals(z)) && x.Equals(z));
  Debug.Assert(x.Equals(null) == false);

  Debug.Assert(a.Equals(different) == false);
  Debug.Assert(different.Equals(a) == false);
  Debug.Assert(x.Equals(different) == false);
  Debug.Assert(different.Equals(x) == false);
  Debug.Assert(y.Equals(different) == false);
  Debug.Assert(different.Equals(y) == false);
  Debug.Assert(z.Equals(different) == false);
  Debug.Assert(different.Equals(z) == false);

}

August 18, 2005

My Testing Of DateTime Parsing Capabilities

  
  public static void TestDateTime()
  {
    TestDateParsing(DateTime.Today.ToString());
    TestDateParsing("16/08/2005");
    TestDateParsing("01-08-2005");
    TestDateParsing("25 December 2005");
    TestDateParsing("");
    TestDateParsing("YES");
    /*
Test with: '18/08/2005 00:00:00'
  '18/08/2005'
  Difference in days from today: 0
Test with: '16/08/2005'
  '16/08/2005'
  Difference in days from today: 2
  Date is WITHIN the last '21' days
Test with: '01-08-2005'
  '01/08/2005'
  Difference in days from today: 17
  Date is WITHIN the last '21' days
Test with: '25 December 2005'
  '25/12/2005'
  Difference in days from today: -128
Test with: ''
  Exception caught: 'String was not recognized as a valid DateTime.'
setting dat e to Minimum Value '01/01/0001' Difference in days from today: 732175 Test with: 'YES' Exception caught: 'The string was not recognized as a valid
DateTime. There i s a unknown word starting at index 0.' setting date to Minimum
Value '01/01/0001' Difference in days from today: 732175 */ } public static void TestDateParsing(string str) { DateTime date; try { WL(string.Concat("Test with: \'", str, "\'")); date = DateTime.Parse(str); } catch (Exception ex) { WL(string.Concat(" Exception caught: \'",ex.Message, "\'
setting date to Minimum Value")); date = DateTime.MinValue; } WL(string.Concat(" \'", date.ToString("dd/MM/yyyy"), "\'")); TimeSpan time = DateTime.Now.Subtract(date); WL(string.Concat(" Difference in days from today: ",time.Days)); const int DAYLIMIT = 21; if ((time.Days <= DAYLIMIT) && (time.Days > 0)) { WL(string.Concat(" Date is WITHIN the last \'", DAYLIMIT,
"\' days")); } }
To parse the string "Mon, 08 Apr 2013 09:56:56 +0100" had to use the parse format "ddd, dd MMM yyyy HH':'mm':'ss K"
Like so:
string form = @"ddd, dd MMM yyyy HH':'mm':'ss K";
DateTime.TryParseExact(pubDateNode.Value, form, 
  System.Globalization.CultureInfo.CurrentCulture,
  System.Globalization.DateTimeStyles.AssumeLocal, 
  out when);