Click here to Skip to main content
Click here to Skip to main content

Commonly Used .NET Coding Patterns in CodeDom

, 31 Oct 2006
Rate this:
Please Sign up or sign in to vote.
A library of CodeDom templates of commonly used coding practices in .NET.

Table of contents

Introduction

The CLR and other .NET code contains many recurring patterns. As these patterns appear in code, they may also appear in code generated by CodeDom graphs, yet generating these patterns requires lot of work, which is quite repetitive. This library contains many pattern implementations for use in your own CodeDom generator, which could help you in decreasing the amount of code you write by thousands of lines.
If you believe there is a pattern that would be perfect for the library, leave a comment and chances are good it will be available, come the next release.

As of October 23, 2006, the project is hosted on CodePlex, with this article serving as an introduction to its abilities.

Argument Assertion patterns

The Argument Assertion patterns are recurring patterns from the CLR in which arguments are checked and exceptions such as ArgumentNullException are raised accordingly. The currently supported assertions are: NotNull, InRange, InLowerBound, InUpperBound, IsInstanceOf, EnumIsDefined and StringNotNullOrEmpty.

In order to include this pattern in your code, your code should look like this:

myMethod.Statements.Add(
    new CodePatternArgumentAssertNotNullStatement("myArgument"));
myMethod.Statements.Add(
    new CodePatternArgumentAssertInRangeStatement("myArgument",
        new CodeFieldReferenceExpression(
            new CodeTypeReferenceExpression("MyType"), "MinValue"), 
        new CodeFieldReferenceExpression(
            new CodeTypeReferenceExpression("MyType"), "MaxValue")));
myMethod.Statements.Add(
    new CodePatternArgumentAssertIsInstanceOfStatement(
                                         "myArgument", typeof(int)));

The code generated by above will be:

if ((myArgument == null))
{
    throw new System.ArgumentNullException("myArgument");
}
if (((myArgument > MyType.MaxValue) 
    || (myArgument < MyType.MinValue)))
{
    throw new System.ArgumentOutOfRangeException("myArgument");
}
if ((myArgument.GetType().IsInstanceOfType(typeof(int)) == false))
{
    throw new System.ArgumentException(string.Format(
              "The argument myArgument must be of type {0}.", 
              typeof(int).FullName), "myArgument");
}

The Assembly Information pattern

Added automatically by Visual Studio, an assembly is identifiable by a set of attributes. This pattern simplifies access to these attributes as properties of a class deriving from CodeCompileUnit.

In order to include this pattern in your code, your code should look like this:

CodePatternCompileUnit unit = new CodePatternCompileUnit();
unit.AssemblyVersion = new Version(1, 0);
unit.AssemblyTitle = "My assembly";
unit.CLSCompliant = true;

The code generated by above will be:

[assembly: System.Reflection.AssemblyVersionAttribute("1.0")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0")]
[assembly: System.Reflection.AssemblyTitleAttribute("My assembly")]
[assembly: System.CLSCompliantAttribute(true)]

The Asynchronous Operation pattern

A recurring pattern from the CLR, asynchronous invocation of methods is required by many systems and components. The implementation presented here is the simplest one, which uses delegates. Documentation on the members generated can be controlled using the HasComments property.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternAsyncOperation(myMethod));

The code generated by above will be:

/// <span class="code-SummaryComment"><summary>
</span>
/// Represents the delegate instance
/// for asynchronous calls to MyMethod.
/// <span class="code-SummaryComment"></summary>
</span>
private MyMethodAsyncCallback m_MyMethodCallback;

/// <span class="code-SummaryComment"><summary>
</span>
/// Executes the MyMethod method asynchronously with a callback.
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="foo">See original method, MyMethod,
</span>
/// for more information about this parameter.<span class="code-SummaryComment"></param>
</span>
/// <span class="code-SummaryComment"><param name="callback">A method to be called when
</span>
/// the asynchronous action completes.<span class="code-SummaryComment"></param>
</span>
/// <span class="code-SummaryComment"><returns>An <see cref="System.IAsyncResult" />
</span>
/// object detailing the asynchronous action.<span class="code-SummaryComment"></returns>
</span>
public System.IAsyncResult BeginMyMethod(int foo, 
                           System.AsyncCallback callback)
{
    if ((this.m_MyMethodCallback == null))
    {
        this.m_MyMethodCallback = 
                new MyMethodAsyncCallback(this.MyMethod);
    }
    return this.m_MyMethodCallback.BeginInvoke(foo, callback, null);
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Executes the MyMethod method asynchronously.
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="foo">See original method, MyMethod,
</span>
/// for more information about this parameter.<span class="code-SummaryComment"></param>
</span>
/// <span class="code-SummaryComment"><returns>An <see cref="System.IAsyncResult" />
</span>
/// object detailing the asynchronous action.<span class="code-SummaryComment"></returns>
</span>
public System.IAsyncResult BeginMyMethod(int foo)
{
    return this.BeginMyMethod(foo, null);
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Synchronously completes an asynchronous call to MyMethod.
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="asyncResult">The <see cref="System.IAsyncResult" />
</span>
/// retrieved from the call to <span class="code-SummaryComment"><see cref="BeginMyMethod" />.</param>
</span>
/// <span class="code-SummaryComment"><exception cref="System.InvalidOperationException">Thrown
</span>
/// when the method is called before the
/// <span class="code-SummaryComment"><see cref="BeginMyMethod" /> method.</exception>
</span>
public void EndMyMethod(System.IAsyncResult asyncResult)
{
    if ((this.m_MyMethodCallback == null))
    {
        throw new System.InvalidOperationException("End of asynchronous" + 
                  " operation attempted when one has not yet begun.");
    }
    this.m_MyMethodCallback.EndInvoke(asyncResult);
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Represents the delegate for asynchronous calls to MyMethod.
/// <span class="code-SummaryComment"></summary>
</span>
public delegate void MyMethodAsyncCallback(int foo);

The BeginProcess/EndProcess pattern

A recurring pattern from System.Data and System.Windows.Forms is the BeginProcess/EndProcess pattern, such as BeginLoad/EndLoad and BeginInit/EndInit. This pattern enables silencing of events with an intuitive interface. Documentation on the members generated can be controlled using the HasComments property.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternBeginEndProcess("Init"));

The code generated by above will be:

/// <span class="code-SummaryComment"><summary>
</span>
/// See <span class="code-SummaryComment"><see cref="IsInInit" />
</span>
/// for information about this field.
/// <span class="code-SummaryComment"></summary>
</span>
private int m_IsInInit;

/// <span class="code-SummaryComment"><summary>
</span>
/// Begins the Init process.
/// <span class="code-SummaryComment"></summary>
</span>
public virtual void BeginInit()
{
    this.m_IsInInit = (this.m_IsInInit + 1);
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Ends the Init process.
/// <span class="code-SummaryComment"></summary>
</span>
public virtual void EndInit()
{
    if ((this.m_IsInInit != 0))
    {
        this.m_IsInInit = (this.m_IsInInit - 1);
    }
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Gets whether the Init process has begun.
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><value>Whether the init process has begun.</value>
</span>
protected bool IsInInit()
{
    return (this.m_IsInInit != 0);
}

Binary Operator patterns

Most binary operators are built into CodeDom, but some aren't. This pattern extends the normal CodeBinaryOperatorExpression to add more operators. Currently supported operator/s: BooleanExclusiveOr.

In order to include this pattern in your code, your code should look like this:

method.Statements.Add(
    new CodeConditionStatement(
        new CodePatternBinaryOperatorExpression(
           new CodeVariableReferenceExpression("bool1"), 
           CodePatternBinaryOperatorType.BooleanExclusiveOr,
           new CodeVariableReferenceExpression("bool2"))
        /* , Contained statements */));

The code generated by above will be:

if (((bool1 == true) && (bool2 == false)) || 
                ((bool1 == false) && (bool2 == true)))
{
    // Contained statements...
}

Code Access Security Decorator patterns

The model of declarative Code Access Security is widespread in the CLR and also very important in many differing situations.

In order to include this pattern in your code, your code should look like this:

UI ui = new DotNetZen.CodeDom.Patterns.Permissions.UI();
ui.Clipboard = 
  System.Security.Permissions.UIPermissionClipboard.AllClipboard;
myMethod.CustomAttributes.Add(new CodePatternCasAttribute(ui));

The code generated by above will be:

[System.Security.Permissions.UIPermissionAttribute(
   System.Security.Permissions.SecurityAction.Demand, 
   Clipboard=System.Security.Permissions.
             UIPermissionClipboard.AllClipboard)]
private void MyMethod()
{
}
Currently all of the Framework's declarative CAS attributes are supported and custom attribute abstractions can be created simply by inheriting from DotNetZen.CodeDom.Patterns.Permissions.Permission.

Compound Assignment patterns

No compound assignment operators are built into CodeDom. This pattern extends the normal CodeAssignStatement to add more operators. Currently supported operator/s: Add, Subtract, Multiply, Divide, Modulus, BitwiseAnd, BitwiseOr.

In order to include this pattern in your code, your code should look like this:

method.Statements.Add(
    new CodePatternCompoundAssignStatement(
        new CodeVariableReferenceExpression("foo"),
        CodePatternCompoundAssignmentOperatorType.Add,
        new CodeVariableReferenceExpression("bar")));

The code generated by above will be:

foo = (foo + bar);

The Cursor Lock pattern

A recurring pattern from System.Windows.Forms is the locking of a Form's Cursor property. This pattern is useful when the process contained within it is quite long.

In order to include this pattern in your code, your code should look like this:

method.Statements.AddRange(
    new CodePatternCursorLock(/* Contained statements */));

The code generated by above will be:

System.Windows.Forms.Cursor cursor0 = this.Cursor;

try
{
    this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
    
    // More code here...
}
finally
{
    this.Cursor = cursor0;
}

The Custom Attribute pattern

Most custom attributes derive from the same template. As a result, creating custom attributes can be a menial task. Documentation on the members generated can be controlled using the HasComments property and the SetComment method.

In order to include this pattern in your code, your code should look like this:

CodePatternCustomAttributeDeclaration attrib = 
      new CodePatternCustomAttributeDeclaration(
          "CoolMetaData",
          AttributeTargets.Struct | 
             AttributeTargets.Class | AttributeTargets.Enum,
          false, true,
          new CodeParameterDeclarationExpression(typeof(int), 
                                               "MetaData"));

attrib.SetComment("MetaData", "The metadata for the attribute");

The code generated by above will be:

[System.AttributeUsageAttribute(((System.AttributeTargets.Enum | 
                                  System.AttributeTargets.Struct) 
        | System.AttributeTargets.Class), 
        AllowMultiple=false, Inherited=true)]
public sealed class CoolMetaDataAttribute : System.Attribute
{
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="MetaData" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_MetaData;

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the
    /// <span class="code-SummaryComment"><see cref="CoolMetaDataAttribute" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    public CoolMetaDataAttribute()
    {
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the
    /// <span class="code-SummaryComment"><see cref="CoolMetaDataAttribute" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="MetaData">The metadata
</span>
    /// for the attribute.<span class="code-SummaryComment"></param>
</span>
    public CoolMetaDataAttribute(int MetaData)
    {
        this.m_MetaData = MetaData;
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the metadata for the attribute.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The metadata for the attribute.</value>
</span>
    public int MetaData
    {
        get
        {
            return this.m_MetaData;
        }
    }
}

The Custom Exception pattern

Most custom exceptions derive from the same template. As a result, creating custom exceptions can be a menial task. Documentation on the members generated can be controlled using the HasComments property and the SetComment method.

In order to include this pattern in your code, your code should look like this:

CodePatternCustomExceptionDeclaration exception = 
    new CodePatternCustomExceptionDeclaration("Foo",
        new CodeParameterDeclarationExpression(
                               typeof(int), "Bar"));

exception.SetComment("Bar", "A healthy snack-bar");

The code generated by above will be:

[System.SerializableAttribute()]
public class FooException : System.Exception
{
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="Bar" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_Bar;

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="FooException" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="Bar">A healthy snack-bar.</param>
</span>
    public FooException(int Bar)
    {
        this.m_Bar = Bar;
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="FooException" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="Bar">A healthy snack-bar.</param>
</span>
    /// <span class="code-SummaryComment"><param name="message">The message in the exception.</param>
</span>
    public FooException(int Bar, string message) : 
        base(message)
    {
        this.m_Bar = Bar;
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="FooException" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="info">The data needed to serialize
</span>
    /// or deserialize an object.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><param name="context">The source and destination
</span>
    /// of a given serialized stream.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><remarks>This member supports the .NET Framework infrastructure
</span>
    /// and is not intended to be used directly from your code.<span class="code-SummaryComment"></remarks>
</span>
    protected FooException(System.Runtime.Serialization.SerializationInfo info, 
              System.Runtime.Serialization.StreamingContext context) : 
              base(info, context)
    {
        this.m_Bar = ((int)(info.GetValue("m_Bar", typeof(int))));
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="FooException" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="Bar">A healthy snack-bar.</param>
</span>
    /// <span class="code-SummaryComment"><param name="message">The message in the exception.</param>
</span>
    /// <span class="code-SummaryComment"><param name="innerException">An exception
</span>
    /// encapsulated in the new exception.<span class="code-SummaryComment"></param>
</span>
    public FooException(int Bar, string message, 
           System.Exception innerException) : 
           base(message, innerException)
    {
        this.m_Bar = Bar;
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets a healthy snack-bar.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>A healthy snack-bar.</value>
</span>
    public int Bar
    {
        get
        {
            return this.m_Bar;
        }
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Populates a <span class="code-SummaryComment"><see
    /// cref="System.Runtime.Serialization.SerializationInfo" />
</span>
    /// with the data needed to serialize the target object.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="info">The <see 
    ///      cref="System.Runtime.Serialization.SerializationInfo" />
</span>
    /// to populate with data.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><param name="context">The destination
</span>
    /// (see <span class="code-SummaryComment"><see cref="System.Runtime.Serialization.StreamingContext" />)
</span>
    /// for this serialization.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentNullException">Thrown when
</span>
    /// the <span class="code-SummaryComment"><paramref name="info" /> parameter is a null reference
</span>
    /// (Nothing in Visual Basic).<span class="code-SummaryComment"></exception>
</span>
    [System.Security.Permissions.SecurityPermissionAttribute(
        System.Security.Permissions.SecurityAction.LinkDemand, 
        Flags=System.Security.Permissions.
              SecurityPermissionFlag.SerializationFormatter)]
    public override void GetObjectData(
                    System.Runtime.Serialization.SerializationInfo 
                    info, 
                    System.Runtime.Serialization.StreamingContext context)
    {
        base.GetObjectData(info, context);
        info.AddValue("m_Bar", this.m_Bar, typeof(int));
    }
}

The Delegate pattern

The Delegate pattern, also known as the EventHandler pattern, is a recurring pattern from the CLR, in which a delegate is created with an object and EventArgs, with a specialized EventArgs class. This pattern is useful for the quick creation of any delegate. Documentation on the members generated can be controlled using the HasComments property and the SetComment method.

In order to include this pattern in your code, your code should look like this:

CodePatternDelegate delegateType = new CodePatternDelegate(
    "ItemChanged",
    new CodeParameterDeclarationExpression(typeof(int), "OldValue"),
    new CodeParameterDeclarationExpression(typeof(int), "NewValue"));

delegateType.SetComment("OldValue", "The value before the change");
delegateType.SetComment("NewValue", "The value after the change");

nameSpace.Types.AddRange(delegateType);

The code generated by above will be:

/// <span class="code-SummaryComment"><summary>
</span>
/// Represents a method that takes a <span class="code-SummaryComment"><see cref="System.Object" />
</span>
/// and <span class="code-SummaryComment"><see cref="ItemChangedEventArgs" />.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="sender">The event's originating object.</param>
</span>
/// <span class="code-SummaryComment"><param name="e">The event's arguments.</param>
</span>
public delegate void ItemChangedEventHandler(object sender, 
                                    ItemChangedEventArgs e);

/// <span class="code-SummaryComment"><summary>
</span>
/// Contains the arguments for events based
/// on the <span class="code-SummaryComment"><see cref="ItemChangedEventHandler" /> delegate.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
public class ItemChangedEventArgs : System.EventArgs
{
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="OldValue" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_OldValue;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="NewValue" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_NewValue;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the
    /// <span class="code-SummaryComment"><see cref="ItemChangedEventArgs" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="OldValue">The value before the change.</param>
</span>
    /// <span class="code-SummaryComment"><param name="NewValue">The value after the change.</param>
</span>
    public ItemChangedEventArgs(int OldValue, int NewValue)
    {
        this.m_OldValue = OldValue;
        this.m_NewValue = NewValue;
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the value before the change.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The value before the change.</value>
</span>
    public virtual int OldValue
    {
        get
        {
            return this.m_OldValue;
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the value after the change.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The value after the change.</value>
</span>
    public virtual int NewValue
    {
        get
        {
            return this.m_NewValue;
        }
    }
}

The Disposable Type pattern

A recurring pattern from the CLR, this recommended pattern for use of the IDisposable interface is used to keep finalizers from running when the object has already been disposed. Documentation on the members generated can be controlled using the automaticComments parameter.
In order to implement the pattern in types that derive from types already implementing this pattern, use the DisposeImplementationType.Inherited value and only an override for void Dispose(bool) will be created.

In order to include this pattern in your code, your code should look like this:

CodePatternTypeDeclaration declaration = 
            new CodePatternTypeDeclaration("MyType");
// ...
declaration.ApplyDisposablePattern(
     new CodeInstanceReferenceExpression(new 
     CodeFieldReferenceExpression(new CodeThisReferenceExpression(), 
     "myReferenceTypeField"), typeof(object)), 
     new CodeInstanceReferenceExpression(new 
     CodeFieldReferenceExpression(new CodeThisReferenceExpression(), 
     "myValueTypeField"), typeof(int)));

The code generated by above will be:

public class MyType : System.IDisposable
{
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Releases all resources used by the object.
    /// <span class="code-SummaryComment"></summary>
</span>
    public void Dispose()
    {
        this.Dispose(true);
        System.GC.SuppressFinalize(this);
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Releases the unmanaged resources used by the object
    /// and optionally releases the managed resources.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="disposing">true to release both managed
</span>
    /// and unmanaged resources; false
    /// to release only unmanaged resources.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><remarks>This method is called by the public
</span>
    /// <span class="code-SummaryComment"><see cref="Dispose()" /> method and the Finalize method.
</span>
    /// <span class="code-SummaryComment"><see cref="Dispose" /> invokes the protected
</span>
    /// <span class="code-SummaryComment"><see cref="Dispose(System.Boolean)" /> method with
</span>
    /// the <span class="code-SummaryComment"><paramref name="disposing" /> parameter set to true.
</span>
    /// Finalize invokes Dispose with
    /// <span class="code-SummaryComment"><paramref name="disposing" /> set to false.
</span>
    /// When the <span class="code-SummaryComment"><paramref name="disposing" /> parameter is true,
</span>
    /// this method releases all resources held
    /// by any managed objects that this object references.
    /// This method invokes the <span class="code-SummaryComment"><see cref="Dispose()" />
</span>
    /// method of each referenced object.
    /// Notes to Inheritors: This method can be called multiple times
    /// by other objects. When overriding it, be careful not to reference
    /// objects that have been previously
    /// disposed of in an earlier call.<span class="code-SummaryComment"></remarks>
</span>
    protected virtual void Dispose(bool disposing)
    {
        if ((disposing == true))
        {
            if ((this.myReferenceTypeField != null))
            {
                ((System.IDisposable)(this.myReferenceTypeField)).Dispose();
            }
            ((System.IDisposable)(this.myValueTypeField)).Dispose();
        }
    }
}

Please note that due to a bug in the .NET Framework, Creation of finalizers is impossible! Please vote on this issue on LadyBug.

The Event pattern

The Event pattern is a recurring pattern from System.Windows.Forms, in which an event has a special invoking method. This pattern is useful for the quick creation of any event. Documentation on the members generated can be controlled using the HasComments property.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternEvent(
    "EventHappened", Scope.Instance, typeof(EventHandler)));

The code generated by above will be:

public event System.EventHandler EventHappened;

/// <span class="code-SummaryComment"><summary>
</span>
/// Raises the <span class="code-SummaryComment"><see cref="EventHappened" /> event.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="e">The value passed
</span>
/// for the event's e parameter.<span class="code-SummaryComment"></param>
</span>
protected virtual int OnEventHappened(System.EventArgs e)
{
    if ((this.EventHappened != null))
    {
        this.EventHappened(this, e);
    }
}

Please note that due to a bug in the .NET Framework, static events cannot be generated! Please vote on this issue on LadyBug.

Language restrictions: Visual Basic does not allow return values from events.

The Flags pattern

The Flags pattern is a recurring pattern from the entire CLR, in which an enum is flagged with the FlagsAttribute attribute. This pattern allocates values automatically and supports up to 63 values.
Each member's CodeMemberField object can be accessed using the Flags indexer.

In order to include this pattern in your code, your code should look like this:

nameSpace.Types.Add(new CodePatternFlags("MyFlags", 
                                      "A", "B", "C"));

The code generated by above will be:

[System.FlagsAttribute()]
public enum MyFlags : int
{
    A = 1,
    B = 2,
    C = 4,
}

The For Each pattern

The For Each pattern is built into C#, but is not native to IL. The pattern iterates over a collection that implements the System.IEnumerable interface. As the C# specification states, the implementation of the said interface is not required, but the implementation of the methods such as MoveNext and GetEnumerator are.

In order to include this pattern in your code, your code should look like this:

method.Statements.AddRange(new CodePatternForEach(
    new CodeTypeReference(typeof(int)), 
    new CodeVariableReferenceExpression("myCollection"),
    new CodeTypeReference("EnumeratorType")
    /* , Contained statements */));

The code generated by above will be:

System.Collections.IEnumerator enumerator0 = 
  ((System.Collections.IEnumerator)(myCollection)).GetEnumerator();

try
{
    for (; enumerator0.MoveNext();)
    {
        int element0 = ((int)(enumerator0.Current));
        // Contained statements ...
    }
}
finally
{
    if (((enumerator0 != null) && 
          enumerator0.GetType().IsInstanceOfType(
                      typeof(System.IDisposable))))
    {
        ((System.IDisposable)(enumerator0)).Dispose();
    }
}

The Get Property/Field pattern

The Get Property/Field pattern is a recurring pattern from the entire CLR, in which a private field is exposed using a property with a get accessor.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternGetField("Value", 
    new CodeTypeReference(typeof(int)), Scope.Instance));

The code generated by above will be:

private int m_Value;

public int Value
{
    get
    {
        return this.m_Value;
    }
}

The Is Instance Of pattern

The Is Instance Of pattern is built into C# as the is keyword, and is also native to IL, yet it is not implemented in CodeDom. The pattern checks whether an object's type implements, inherits or is the queried type.

In order to include this pattern in your code, your code should look like this:

method.Statements.Add(new CodePatternIsInstExpression(
          new CodeVariableReferenceExpression("myVariable"),
          new CodeTypeReference(typeof(IMyInterface))));

The code generated by above will be:

myVariable.GetType().IsInstanceOfType(typeof(IMyInterface))

The Lock pattern

The Lock pattern is built into C#, but is not native to IL. The pattern locks a resource using the System.Threading.Monitor class.

In order to include this pattern in your code, your code should look like this:

method.Statements.AddRange(new CodePatternLock(
          new CodeFieldReferenceExpression(
               new CodeThisReferenceExpression(), "SyncRoot")
          /* , Contained statements... */));

The code generated by above will be:

object lockCachedExpr0 = this.SyncRoot;
System.Threading.Monitor.Enter(lockCachedExpr0);

try
{
    // Contained statements...
}
finally
{
    System.Threading.Monitor.Exit(lockCachedExpr0);
}

The Nullable Value Type Property pattern

The Nullable Value Type Property pattern is used in CLR 1.x (pre-generics and Nullable<T>) to denote a value type property with a null value. This pattern is used predominately in Typed DataSets.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternNullableProperty("Value", 
         new CodeTypeReference(typeof(int)), Scope.Instance));

The code generated by above will be:

private int m_Value;

/// <span class="code-SummaryComment"><summary>
</span>
/// See <span class="code-SummaryComment"><see cref="IsValueNull" /> for information about this field.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
private bool m_IsValueNull = true;

public int Value
{
    get
    {
        if ((this.m_IsValueNull == true))
        {
            throw new System.InvalidOperationException("Can not" + 
                  " get value when it is null. Check for " + 
                  "nullability by calling IsValueNull.");
        }
        return this.m_Value;
    }
    set
    {
        this.m_Value = value;
        this.m_IsValueNull = false;
    }
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Gets whether the value of <span class="code-SummaryComment"><see cref="Value" /> is null.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><value>Whether the value of <see cref="Value" /> is null.</value>
</span>
public bool IsValueNull
{
    get
    {
        return this.m_IsValueNull;
    }
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Sets the value of <span class="code-SummaryComment"><see cref="Value" /> to null.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
public void SetValueNull()
{
    this.m_IsValueNull = true;
}

The Observer pattern

The Observer pattern is a classic pattern which allows subscribers to be notified of the changes to a value. This implementation allows changes to the value of a property to be announced using an event. Documentation on the members generated can be controlled using the HasComments property.

In order to include this pattern in your code, your code should look like this:

type.Members.AddRange(new CodePatternObserver("MyValue", 
    new CodeTypeReference(typeof(int)), Scope.Instance));

The code generated by above will be:

/// <span class="code-SummaryComment"><summary>
</span>
/// Value for the property <span class="code-SummaryComment"><see cref="MyValue" />.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
private int m_MyValue;

public int MyValue
{
    get
    {
        return this.m_MyValue;
    }
    set
    {
        if ((this.m_MyValue != value))
        {
            int oldValue = this.m_MyValue;
            this.m_MyValue = value;
            this.OnMyValueChanged(new MyValueChangedEventArgs(oldValue, 
                                                        this.m_MyValue));
        }
    }
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Occurs when the <span class="code-SummaryComment"><see cref="MyValue" /> property is changed.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
public event MyValueChangedEventHandler MyValueChanged;

/// <span class="code-SummaryComment"><summary>
</span>
/// Raises the <span class="code-SummaryComment"><see cref="MyValueChanged" /> event.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="e">The value passed
</span>
/// for the event's e parameter.<span class="code-SummaryComment"></param>
</span>
protected virtual void OnMyValueChanged(MyValueChangedEventArgs e)
{
    if ((this.MyValueChanged != null))
    {
        this.MyValueChanged(this, e);
    }
}

/// <span class="code-SummaryComment"><summary>
</span>
/// Represents a method that takes a <span class="code-SummaryComment"><see cref="System.Object" />
</span>
/// and <span class="code-SummaryComment"><see cref="MyValueChangedEventArgs" />.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
/// <span class="code-SummaryComment"><param name="sender">The event's originating object.</param>
</span>
/// <span class="code-SummaryComment"><param name="e">The event's arguments.</param>
</span>
public delegate void MyValueChangedEventHandler(object sender, 
                                   MyValueChangedEventArgs e);

/// <span class="code-SummaryComment"><summary>
</span>
/// Contains the arguments for events based
/// on the <span class="code-SummaryComment"><see cref="MyValueChangedEventHandler" /> delegate.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
public class MyValueChangedEventArgs : System.EventArgs
{
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="OldValue" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_OldValue;

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Value for the property <span class="code-SummaryComment"><see cref="NewValue" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_NewValue;

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance
    /// of the <span class="code-SummaryComment"><see cref="MyValueChangedEventArgs" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="OldValue">The value before the change.</param>
</span>
    /// <span class="code-SummaryComment"><param name="NewValue">The current value.</param>
</span>
    public MyValueChangedEventArgs(int OldValue, int NewValue)
    {
        this.m_OldValue = OldValue;
        this.m_NewValue = NewValue;
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the value before the change.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The value before the change.</value>
</span>
    public virtual int OldValue
    {
        get
        {
            return this.m_OldValue;
        }
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the current value.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The current value.</value>
</span>
    public virtual int NewValue
    {
        get
        {
            return this.m_NewValue;
        }
    }
}

The Serializable Type pattern

A pattern from the CLR, this pattern applies one of the four different types of serialization in the framework: Basic, Selective and Custom for types new to serialization and ones inheriting it. Documentation on the members generated can be controlled using the automaticComments parameter.

In order to include this pattern in your code, your code should look like this:

CodePatternTypeDeclaration declaration = 
                     new CodePatternTypeDeclaration("MyType");
decl.Members.Add(new CodeMemberField(typeof(int), "myField"));
decl.ApplySerializablePattern(SerializationType.NewCustom, "myField");

The code generated by above will be:

[System.SerializableAttribute()]
public class MyType : System.Runtime.Serialization.ISerializable
{
    private int myField;

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="MyType" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="info">The data needed
</span>
    /// to serialize or deserialize an object.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><param name="context">The source
</span>
    /// and destination of a given serialized stream.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><remarks>This member supports the .NET Framework
</span>
    /// infrastructure and is not intended
    /// to be used directly from your code.<span class="code-SummaryComment"></remarks>
</span>
    protected MyType(System.Runtime.Serialization.SerializationInfo info, 
              System.Runtime.Serialization.StreamingContext context)
    {
        this.myField = ((int)(info.GetValue("myField", typeof(int))));
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Populates a <span class="code-SummaryComment"><see cref="System.Runtime.Serialization.
    ///                        SerializationInfo" />
</span>
    /// with the data needed to serialize the target object.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="info">The <see 
    /// cref="System.Runtime.Serialization.SerializationInfo" />
</span>
    /// to populate with data.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><param name="context">The destination (see <see 
    /// cref="System.Runtime.Serialization.StreamingContext" />)
</span>
    /// for this serialization.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentNullException">Thrown
</span>
    /// when the <span class="code-SummaryComment"><paramref name="info" /> parameter is a null
</span>
    /// reference (Nothing in Visual Basic).<span class="code-SummaryComment"></exception>
</span>
    [System.Security.Permissions.SecurityPermissionAttribute(
        System.Security.Permissions.SecurityAction.LinkDemand, 
        Flags=System.Security.Permissions.
              SecurityPermissionFlag.SerializationFormatter)]
    public virtual void GetObjectData(
           System.Runtime.Serialization.SerializationInfo 
           info, System.Runtime.Serialization.StreamingContext context)
    {
        if ((info == null))
        {
            throw new System.ArgumentNullException("info");
        }
        info.AddValue("myField", this.myField, typeof(int));
    }
}

The Singleton pattern

The Singleton pattern is a classic pattern which allows a class to only have one instance in the application. This implementation follows the best practices and is thread-safe. It also allows lazy-loading or pre-loading implementation. Documentation on the members generated can be controlled using the HasComments property.

In order to include this pattern in your code, your code should look like this:

nameSpace.Types.Add(new CodePatternSingleton("Foo", 
                                   LoadType.LazyLoad));

The code generated by above will be:

public class Foo
{
    private Foo()
    {
    }

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets the single instance of type <span class="code-SummaryComment"><see cref="Foo" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The single instance of type <see cref="Foo" />.</value>
</span>
    public static Foo Instance
    {
        get
        {
            return InstanceContainer.Instance;
        }
    }

    class InstanceContainer
    {
        private static Foo m_Instance = new Foo();

        static InstanceContainer()
        {
        }

        private InstanceContainer()
        {
        }

        public static Foo Instance
        {
            get
            {
                return InstanceContainer.m_Instance;
            }
        }
    }
}

The Typed Collection pattern

The Typed Collection pattern is a woe on the way to completely strongly typed implementations. This is one of the most common type patterns, and also one of those patterns which can have 1001 different implementations. This implementation includes optional events (with the ability to silence them when loading data), a complete IList implementation and additional convenience constructors and methods, such as AddRange and ToArray.

In order to include this pattern in your code, your code should look like this:

nameSpace.Types.Add(new CodePatternTypedCollection(
                      typeof(int), CollectionEvents.All));

The code generated by above will be:

/// <span class="code-SummaryComment"><summary>
</span>
/// Represents a collection of <span class="code-SummaryComment"><see cref="Int32" /> elements.
</span>
/// <span class="code-SummaryComment"></summary>
</span>
[System.SerializableAttribute()]
public class Int32Collection : System.Collections.CollectionBase
{
    /// <span class="code-SummaryComment"><summary>
</span>
    /// See <span class="code-SummaryComment"><see cref="IsInLoad" /> for information about this field.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    private int m_IsInLoad;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance
    /// of the <span class="code-SummaryComment"><see cref="Int32Collection" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    public Int32Collection()
    {
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the
    /// <span class="code-SummaryComment"><see cref="Int32Collection" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="values">A list of objects of type
</span>
    /// <span class="code-SummaryComment"><see cref="Int32" /> to initialize
</span>
    /// the collection with.<span class="code-SummaryComment"></param>
</span>
    public Int32Collection(params int[] values)
    {
        if ((values == null))
        {
            throw new System.ArgumentNullException("values");
        }
        this.InnerList.Capacity = values.Length;
        this.BeginLoad();
        try
        {
            this.AddRange(values);
        }
        finally
        {
            this.EndLoad();
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Initializes a new instance of the
    /// <span class="code-SummaryComment"><see cref="Int32Collection" /> class.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="collection">An object of type
</span>
    /// <span class="code-SummaryComment"><see cref="Int32Collection" /> containing
</span>
    /// objects to be copied into the new collection.<span class="code-SummaryComment"></param>
</span>
    public Int32Collection(Int32Collection collection)
    {
        if ((collection == null))
        {
            throw new System.ArgumentNullException("collection");
        }
        this.InnerList.Capacity = collection.Count;
        this.BeginLoad();
        try
        {
            this.AddRange(collection);
        }
        finally
        {
            this.EndLoad();
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets or sets the <span class="code-SummaryComment"><see cref="Int32" />
</span>
    /// at position <span class="code-SummaryComment"><paramref name="index" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>The <see cref="Int32" /> at position
</span>
    /// <span class="code-SummaryComment"><paramref name="index" />.</value>
</span>
    /// <span class="code-SummaryComment"><param name="index">The position
</span>
    /// of the <span class="code-SummaryComment"><see cref="Int32" />.</param>
</span>
    public int this[int index]
    {
        get
        {
            return ((int)(this.List[index]));
        }
        set
        {
            this.List[index] = value;
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets an object that can be used
    /// to synchronize access to the collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>An object that can be used to synchronize
</span>
    /// access to the collection.<span class="code-SummaryComment"></value>
</span>
    public object SyncRoot
    {
        get
        {
            return this.List.SyncRoot;
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs when the collection begins
    /// the process of removing all elements.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To indicate that clearing the collection
</span>
    /// is not possible, throw an exception
    /// from an attached method.<span class="code-SummaryComment"></remarks>
</span>
    public event System.EventHandler Clearing;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs after the collection completes
    /// the process of removing all elements.
    /// <span class="code-SummaryComment"></summary>
</span>
    public event System.EventHandler Cleared;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs when the collection begins
    /// the process of inserting an element.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To indicate that inserting this element is invalid,
</span>
    /// throw an exception from an attached method. To indicate
    /// that the element is simply invalid, use the
    /// <span class="code-SummaryComment"><see cref="Validating" /> event.</remarks>
</span>
    public event EventHandler Inserting;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs after the collection completes
    /// the process of inserting an element.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To prevent the insertion from taking place,
</span>
    /// throw an exception from an attached method.<span class="code-SummaryComment"></remarks>
</span>
    public event EventHandler Inserted;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs when the collection begins
    /// the process of removing an element.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To indicate that removing this element is invalid,
</span>
    /// throw an exception from an attached method. To indicate that
    /// the element is simply invalid, use the
    /// <span class="code-SummaryComment"><see cref="Validating" /> event.</remarks>
</span>
    public event EventHandler Removing;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs after the collection completes
    /// the process of removing an element.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To prevent the removal from taking place,
</span>
    /// throw an exception from an attached method.<span class="code-SummaryComment"></remarks>
</span>
    public event EventHandler Removed;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs when the collection begins the process
    /// of setting an element at a certain position.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To indicate that setting this element
</span>
    /// at this position is invalid, throw an exception from an attached
    /// method. To indicate that the element is simply invalid,
    /// use the <span class="code-SummaryComment"><see cref="Validating" /> event.</remarks>
</span>
    public event SetEventHandler Setting;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs after the collection completes the process
    /// of setting an element at a certain position.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>To prevent the settng action from taking
</span>
    /// place, throw an exception from an attached method.<span class="code-SummaryComment"></remarks>
</span>
    public event SetEventHandler Set;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Occurs when the collection asks for validation
    /// of an item that is to be added into it.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><remarks>If the item is invalid,
</span>
    /// throw an exception from an attached method.
    /// Checks that already take place are that the value is not a null
    /// reference (Nothing in Visual Basic) and that it is of/derives
    /// from <span class="code-SummaryComment"><see cref="Int32" />.</remarks>
</span>
    public event ValidationEventHandler Validating;
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Begins the Load process.
    /// <span class="code-SummaryComment"></summary>
</span>
    public virtual void BeginLoad()
    {
        this.m_IsInLoad = (this.m_IsInLoad + 1);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Ends the Load process.
    /// <span class="code-SummaryComment"></summary>
</span>
    public virtual void EndLoad()
    {
        if ((this.m_IsInLoad != 0))
        {
            this.m_IsInLoad = (this.m_IsInLoad - 1);
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Gets whether the Load process has begun.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><value>Whether the Load process has begun.</value>
</span>
    protected bool IsInLoad()
    {
        return (this.m_IsInLoad != 0);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Inserts an element into the collection at the specified index.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// <span class="code-SummaryComment"><paramref name="value" /> should be inserted.</param>
</span>
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Int32" /> to insert.</param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentOutOfRangeException">
</span>
    /// <span class="code-SummaryComment"><paramref name="index" /> is less than zero or is greater
</span>
    /// than <span class="code-SummaryComment"><see cref="System.Collections.CollectionBase.Count" />.
</span>
    /// <span class="code-SummaryComment"></exception>
</span>
    public void Insert(int index, int value)
    {
        this.List.Insert(index, value);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Removes the first occurrence of a specific
    /// <span class="code-SummaryComment"><see cref="Int32" /> from the collection.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Int32" />
</span>
    /// to remove from the collection.<span class="code-SummaryComment"></param>
</span>
    public void Remove(int value)
    {
        this.List.Remove(value);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Determines whether an element is in the collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Int32" />
</span>
    /// to locate in the collection.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><returns>true if <paramref name="value" />
</span>
    /// is found in the collection; otherwise, false.<span class="code-SummaryComment"></returns>
</span>
    public bool Contains(int value)
    {
        return this.List.Contains(value);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Searches for the specified <span class="code-SummaryComment"><see cref="Int32" />
</span>
    /// and returns the zero-based index of the first
    /// occurrence within the entire collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Int32" />
</span>
    /// to locate in the collection.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><returns>The zero-based index of the first occurrence
</span>
    /// of <span class="code-SummaryComment"><paramref name="value" /> within the entire collection,
</span>
    /// if found; otherwise, -1.<span class="code-SummaryComment"></returns>
</span>
    public int IndexOf(int value)
    {
        return this.List.IndexOf(value);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Adds an object to the end of the collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="value">The <see cref="Int32" />
</span>
    /// to be added to the end of the collection.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><returns>The collection index at which the
</span>
    /// <span class="code-SummaryComment"><paramref name="value" /> has been added.</returns>
</span>
    public int Add(int value)
    {
        return this.List.Add(value);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Adds the elements of an array to the end of the collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="values">The array whose elements should be
</span>
    /// added to the end of the collection.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentNullException">
</span>
    /// <span class="code-SummaryComment"><paramref name="values" /> is a null reference
</span>
    /// (Nothing in Visual Basic).<span class="code-SummaryComment"></exception>
</span>
    public void AddRange(int[] values)
    {
        if ((values == null))
        {
            throw new System.ArgumentNullException("values");
        }
        System.Collections.IEnumerator enumerator0 = 
           ((System.Collections.IEnumerable)(values)).GetEnumerator();
        try
        {
            for (
                ; (enumerator0.MoveNext() == true); 
                )
            {
                int element0 = ((int)(enumerator0.Current));
                this.List.Add(element0);
            }
        }
        finally
        {
            if (((enumerator0 != null) 
                && enumerator0.GetType().IsInstanceOfType(
                   typeof(System.IDisposable))))
            {
                ((System.IDisposable)(enumerator0)).Dispose();
            }
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Adds the elements of a collection to the end of the collection.
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="collection">The collection whose elements
</span>
    /// should be added to the end of the collection.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentNullException">
</span>
    /// <span class="code-SummaryComment"><paramref name="collection" /> is a null reference
</span>
    /// (Nothing in Visual Basic).<span class="code-SummaryComment"></exception>
</span>
    public void AddRange(Int32Collection collection)
    {
        if ((collection == null))
        {
            throw new System.ArgumentNullException("collection");
        }
        System.Collections.IEnumerator enumerator1 = 
           ((System.Collections.IEnumerable)
            (collection.InnerList)).GetEnumerator();
        try
        {
            for (
                ; (enumerator1.MoveNext() == true); 
                )
            {
                int element1 = ((int)(enumerator1.Current));
                this.List.Add(element1);
            }
        }
        finally
        {
            if (((enumerator1 != null) 
                && enumerator1.GetType().IsInstanceOfType(
                   typeof(System.IDisposable))))
            {
                ((System.IDisposable)(enumerator1)).Dispose();
            }
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Copies the entire collection to a compatible one-dimensional
    /// <span class="code-SummaryComment"><see cref="System.Array" />, starting at the specified
</span>
    /// <span class="code-SummaryComment"><paramref name="index" /> of the target array.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="array">The one-dimensional
</span>
    /// <span class="code-SummaryComment"><see cref="System.Array" />
</span>
    /// that is the destination of the elements copied from collection.
    /// The <span class="code-SummaryComment"><see cref="System.Array" /> must
</span>
    /// have zero-based indexing.<span class="code-SummaryComment"></param>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index in <paramref
    /// name="array" /> at which copying begins.</param>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentNullException"><paramref
    /// name="array" /> is a null reference
</span>
    /// (Nothing in Visual Basic).<span class="code-SummaryComment"></exception>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentOutOfRangeException">
</span>
    /// <span class="code-SummaryComment"><paramref name="index" /> is less than zero.</exception>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentException"><paramref
    /// name="array" /> is multidimensional.</exception>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentException">
</span>
    /// <span class="code-SummaryComment"><paramref name="index" />
</span>
    /// is equal to or greater than the length
    /// of <span class="code-SummaryComment"><paramref name="array" />.</exception>
</span>
    /// <span class="code-SummaryComment"><exception cref="System.ArgumentException">The number
</span>
    /// of elements in the source collection
    /// is greater than the available space
    /// from <span class="code-SummaryComment"><paramref name="index" /> to the end of the destination
</span>
    /// <span class="code-SummaryComment"><paramref name="array" />.</exception>
</span>
    /// <span class="code-SummaryComment"><remarks>The specified array's elements must be of type
</span>
    /// <span class="code-SummaryComment"><see cref="Int32" /> or any of its derivatives.</remarks>
</span>
    public void CopyTo(System.Array array, int index)
    {
        this.List.CopyTo(array, index);
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Copies the elements of the collection
    /// to a new <span class="code-SummaryComment"><see cref="Int32" /> array.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><returns>An array of <see cref="Int32" /> containing
</span>
    /// copies of the elements of the collection.<span class="code-SummaryComment"></returns>
</span>
    public int[] ToArray()
    {
        return ((int[])(this.InnerList.ToArray(typeof(Int32))));
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Clearing" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    protected override void OnClear()
    {
        if (((this.IsInLoad() == false) 
            && (this.Clearing != null)))
        {
            this.Clearing(this, System.EventArgs.Empty);
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Cleared" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    protected override void OnClearComplete()
    {
        if (((this.IsInLoad() == false) 
            && (this.Cleared != null)))
        {
            this.Cleared(this, System.EventArgs.Empty);
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Inserting" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// to insert <span class="code-SummaryComment"><paramref name="value" />.</param>
</span>
    /// <span class="code-SummaryComment"><param name="value">The new value of the element
</span>
    /// at <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnInsert(int index, object value)
    {
        if (((this.IsInLoad() == false) 
            && (this.Inserting != null)))
        {
            this.Inserting(this, new EventArgs(index, ((int)(value))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Inserted" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// to insert <span class="code-SummaryComment"><paramref name="value" />.</param>
</span>
    /// <span class="code-SummaryComment"><param name="value">The new value of the element
</span>
    /// at <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnInsertComplete(int index, object value)
    {
        if (((this.IsInLoad() == false) 
            && (this.Inserted != null)))
        {
            this.Inserted(this, new EventArgs(index, ((int)(value))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Removing" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// <span class="code-SummaryComment"><paramref name="value" /> can be found.</param>
</span>
    /// <span class="code-SummaryComment"><param name="value">The value of the element to remove
</span>
    /// from <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnRemove(int index, object value)
    {
        if (((this.IsInLoad() == false) 
            && (this.Removing != null)))
        {
            this.Removing(this, new EventArgs(index, 
                         ((int)(value))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Removed" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// <span class="code-SummaryComment"><paramref name="value" /> can be found.</param>
</span>
    /// <span class="code-SummaryComment"><param name="value">The value of the element
</span>
    /// to remove from <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnRemoveComplete(int index, object value)
    {
        if (((this.IsInLoad() == false) 
            && (this.Removed != null)))
        {
            this.Removed(this, new EventArgs(index, 
                        ((int)(value))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Setting" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// <span class="code-SummaryComment"><paramref name="oldValue" /> can be found.</param>
</span>
    /// <span class="code-SummaryComment"><param name="oldValue">The value to replace
</span>
    /// with <span class="code-SummaryComment"><paramref name="newValue" />.</param>
</span>
    /// <span class="code-SummaryComment"><param name="newValue">The new value of the
</span>
    /// element at <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnSet(int index, 
              object oldValue, object newValue)
    {
        if (((this.IsInLoad() == false) 
            && (this.Setting != null)))
        {
            this.Setting(this, new SetEventArgs(index, 
                        ((int)(oldValue)), ((int)(newValue))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Set" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="index">The zero-based index at which
</span>
    /// <span class="code-SummaryComment"><paramref name="oldValue" /> can be found.</param>
</span>
    /// <span class="code-SummaryComment"><param name="oldValue">The value to replace
</span>
    /// with <span class="code-SummaryComment"><paramref name="newValue" />.</param>
</span>
    /// <span class="code-SummaryComment"><param name="newValue">The new value of the element
</span>
    /// at <span class="code-SummaryComment"><paramref name="index" />.</param>
</span>
    protected override void OnSetComplete(int index, 
              object oldValue, object newValue)
    {
        if (((this.IsInLoad() == false) 
            && (this.Set != null)))
        {
            this.Set(this, new SetEventArgs(index, 
                    ((int)(oldValue)), ((int)(newValue))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Raises the <span class="code-SummaryComment"><see cref="Validating" /> event.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="value">The object to validate.</param>
</span>
    protected override void OnValidate(object value)
    {
        base.OnValidate(value);
        if ((value.GetType().IsInstanceOfType(typeof(int)) == false))
        {
            throw new System.ArgumentException(
                  string.Format("The argument" + 
                  " value must be of type {0}.", 
                  typeof(int).FullName), "value");
        }
        if (((this.IsInLoad() == false) 
            && (this.Validating != null)))
        {
            this.Validating(this, 
                new ValidationEventArgs(((int)(value))));
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Represents a method that takes a <span class="code-SummaryComment"><see cref="System.Object" />
</span>
    /// and <span class="code-SummaryComment"><see cref="EventArgs" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="sender">The event's originating object.</param>
</span>
    /// <span class="code-SummaryComment"><param name="e">The event's arguments.</param>
</span>
    public delegate void EventHandler(object sender, EventArgs e);
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Contains the arguments for events based
    /// on the <span class="code-SummaryComment"><see cref="EventHandler" /> delegate.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    public class EventArgs : System.EventArgs
    {
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="Index" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_Index;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="Value" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_Value;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Initializes a new instance
        /// of the <span class="code-SummaryComment"><see cref="EventArgs" /> class.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><param name="Index">The index of the value.</param>
</span>
        /// <span class="code-SummaryComment"><param name="Value">The value raised by the event.</param>
</span>
        public EventArgs(int Index, int Value)
        {
            this.m_Index = Index;
            this.m_Value = Value;
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the index of the value.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The index of the value.</value>
</span>
        public virtual int Index
        {
            get
            {
                return this.m_Index;
            }
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the value raised by the event.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The value raised by the event.</value>
</span>
        public virtual int Value
        {
            get
            {
                return this.m_Value;
            }
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Represents a method that takes a
    /// <span class="code-SummaryComment"><see cref="System.Object" />
</span>
    /// and <span class="code-SummaryComment"><see cref="SetEventArgs" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="sender">The event's originating object.</param>
</span>
    /// <span class="code-SummaryComment"><param name="e">The event's arguments.</param>
</span>
    public delegate void SetEventHandler(object sender, 
                                         SetEventArgs e);
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Contains the arguments for events based on the
    /// <span class="code-SummaryComment"><see cref="SetEventHandler" /> delegate.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    public class SetEventArgs : System.EventArgs
    {
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="Index" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_Index;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="OldValue" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_OldValue;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="NewValue" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_NewValue;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Initializes a new instance of the
        /// <span class="code-SummaryComment"><see cref="SetEventArgs" /> class.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><param name="Index">The zero-based index
</span>
        /// at which oldValue can be found.<span class="code-SummaryComment"></param>
</span>
        /// <span class="code-SummaryComment"><param name="OldValue">The value
</span>
        /// to replace with newValue.<span class="code-SummaryComment"></param>
</span>
        /// <span class="code-SummaryComment"><param name="NewValue">The new value
</span>
        /// of the element at index.<span class="code-SummaryComment"></param>
</span>
        public SetEventArgs(int Index, int OldValue, int NewValue)
        {
            this.m_Index = Index;
            this.m_OldValue = OldValue;
            this.m_NewValue = NewValue;
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the zero-based index at which oldValue can be found.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The zero-based index at which
</span>
        /// oldValue can be found.<span class="code-SummaryComment"></value>
</span>
        public virtual int Index
        {
            get
            {
                return this.m_Index;
            }
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the value to replace with newValue.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The value to replace with newValue.</value>
</span>
        public virtual int OldValue
        {
            get
            {
                return this.m_OldValue;
            }
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the new value of the element at index.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The new value of the element at index.</value>
</span>
        public virtual int NewValue
        {
            get
            {
                return this.m_NewValue;
            }
        }
    }
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Represents a method that takes a <span class="code-SummaryComment"><see cref="System.Object" />
</span>
    /// and <span class="code-SummaryComment"><see cref="ValidationEventArgs" />.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="sender">The event's originating object.</param>
</span>
    /// <span class="code-SummaryComment"><param name="e">The event's arguments.</param>
</span>
    public delegate void ValidationEventHandler(object sender, 
                                        ValidationEventArgs e);
    
    /// <span class="code-SummaryComment"><summary>
</span>
    /// Contains the arguments for events based
    /// on the <span class="code-SummaryComment"><see cref="ValidationEventHandler" /> delegate.
</span>
    /// <span class="code-SummaryComment"></summary>
</span>
    public class ValidationEventArgs : System.EventArgs
    {
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Value for the property <span class="code-SummaryComment"><see cref="Value" />.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        private int m_Value;
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Initializes a new instance of the
        /// <span class="code-SummaryComment"><see cref="ValidationEventArgs" /> class.
</span>
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><param name="Value">The value to be validated.</param>
</span>
        public ValidationEventArgs(int Value)
        {
            this.m_Value = Value;
        }
        
        /// <span class="code-SummaryComment"><summary>
</span>
        /// Gets the value to be validated.
        /// <span class="code-SummaryComment"></summary>
</span>
        /// <span class="code-SummaryComment"><value>The value to be validated.</value>
</span>
        public virtual int Value
        {
            get
            {
                return this.m_Value;
            }
        }
    }
}

Please note that a bug in the .NET Frameworks up to (and not including) 2.0 does not allow for creation of parameter arrays, which means that the pattern is incomplete when used with these versions.

Unary Operator patterns

No unary operators are built into CodeDom. This pattern extends the normal CodeBinaryOperatorExpression to add more operators. Currently supported operator/s: BooleanNot, BooleanIsTrue, IsNull, NotNull.

In order to include this pattern in your code, your code should look like this:

method.Statements.Add(
    new CodeConditionStatement(
        new CodePatternBinaryOperatorExpression(
            CodePatternUnaryOperatorType.BooleanNot,
            new CodeVariableReferenceExpression("bool1"))
        /* , Contained statements */));

The code generated by above will be:

if (bool1 == false)
{
    // Contained statements...
}

The Using pattern

The Using pattern is built into C#, but is not native to IL. The pattern uses a resource that implements the System.IDisposable interface, then releases it.

In order to include this pattern in your code, your code should look like this:

method.Statements.AddRange(new CodePatternUsing(
    new CodeVariableDeclarationStatement(
                typeof(System.Drawing.Image), "image"),
    ResourceType.ReferenceType
    /* , Contained statements... */));

The code generated by above will be:

System.Drawing.Image image;

try
{
    // Contained statements...
}
finally
{
    if ((image != null))
    {
        ((System.IDisposable)(image)).Dispose();
    }
}

XML Comment patterns

XML comments are the standard method of writing member comments which are descriptive and easy to parse using tool such as NDoc. The currently supported tags and their class equivalents are:

  • <summary> - SummaryStatements.
  • <c> - TextAsCodeExpression.
  • <code> - MultilineTextAsCodeStatements.
  • <example> - ExampleStatements.
  • <exception> - ExceptionStatements.
  • <list> - ListStatements.
  • <para> - ParagraphExpression.
  • <param> - ParameterStatements.
  • <paramref> - ParameterReferenceExpression.
  • <remarks> - RemarksStatements.
  • <returns> - ReturnsStatements.
  • <see> - SeeExpression.
  • <seealso> - SeeAlsoStatements.
  • <value> - ValueStatements.
Also, there are several templates: CommentsForConstructor, CommentsForMethod, CommentsForProperty and CommentsForIndexer.

On a side note, Sandcastle has been released by Microsoft, but it has not yet been finalized. Once it is, classes will be added to support the more advanced features it offers.

History

  • 2006-10-31 - Version 1.8.
    1. The Code Access Security Decorator Patterns have been added.
    2. The Assembly Information Pattern has been added.
    3. Security demand added to GetObjectData in the Serializable Type Pattern.
    4. XML Comment Patterns moved to the .Xml namespace and had their CodeXmlComment prefix removed (too long).
    5. Binaries now target .NET 2.0 instead of .NET 1.1, but they are mostly still backwards compatible.
  • 2006-09-23: Version 1.7.
    1. The Nullable Value Type Property Pattern has been added.
    2. The Enum.IsDefined and String.IsNullOrEmpty assertions have been added.
    3. The Serializable Type Pattern has been added.
    4. The Disposable Type Pattern is now a part of CodePatternTypeDeclaration.
  • 2006-04-29: Version 1.6.
    1. The Asynchronous Operation Pattern has been added.
    2. The Disposable Type Pattern has been added.
    3. The XML Comment Patterns have been added.
    4. Automatic documentation of the Begin/End Process, Custom Attribute, Custom Exception, Delegate, Event, Observer, Singleton, and Typed Collection patterns.
    5. The Unary Operators IsNull and NotNull have been added.
    6. You can now access each flag's CodeMemberField in the Flags Pattern.
    7. The Singleton Pattern (Lazy Load) no longer publicly exposes the internally used class InstanceContainer.
    8. The Typed Collection Pattern's ToArray method has been fixed.
    9. The work is now licensed under the Creative Commons Attribution 2.5 License. You can copy, freely distribute, derive and even use the code in a commercial product, but you must attribute it to the author.
  • 2006-03-31: Version 1.5.
    1. The Typed Collection pattern has been added.
    2. The Argument Assertion patterns have been added.
    3. Assembly and all types are now CLSCompliant.
    4. All types are now marked as Serializable.
    5. The Custom Attribute pattern now produces sealed attributes, to increase the efficiency of generated code.
    6. Several overload additions and bug fixes.
  • 2006-02-10: Version 1.4.
    1. Compatible with generation for Visual Basic.
    2. Custom Exception pattern altered to take CodeParameterDeclarationExpressions instead of CodePatternGetFields.
    3. The Event pattern now has an overload that takes a delegate type (and deduces the parameters and the return type).
    4. The For Each pattern now works according to the C# specifications.
    5. Several bug fixes.
  • 2006-01-28: Version 1.3.
    1. Assembly renamed to DotNetZen.CodeDom.Patterns.
    2. The Custom Attribute pattern has been added.
    3. The Custom Exception pattern has been added.
  • 2006-01-13: Version 1.2.
    1. Binary and unary operator patterns have been added.
    2. Compound assignment patterns have been added.
  • 2005-11-11: Version 1.1.
    1. The Cursor Lock pattern now changes the cursor back to its original icon, rather than Cursors.Default.
    2. The For Each pattern has been added.
    3. The Is Instance Of pattern has been added.
    4. Boolean flags for scope are now implemented using the Scope enumeration.
    5. Boolean flags for the resource type on the Using pattern are now implemented using the ResourceType enumeration.
    6. Boolean flags for the load type on the Singleton pattern are now implemented using the LoadType enumeration.
  • 2005-10-30: Initial release.

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License
(Can copy, distribute, derive, use commercially; Must attribute to author)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Omer van Kloeten
Web Developer
Israel Israel
Omer van Kloeten is a senior .NET consultant and a lecturer at the Sela Group.
 
My blogs:
English: http://weblogs.asp.net/OKloeten/
English and Hebrew: http://blogs.microsoft.co.il/blogs/omer
 
You can find more details about the Sela Group here:
http://www.sela.co.il

Comments and Discussions

 
QuestionBug in CodePatternLock ? Pinmemberzebadiah8131-Oct-07 14:46 
GeneralUnary Pattern PinmemberGilesb4-Feb-07 6:01 
AnswerRe: Unary Pattern PinmemberOmer van Kloeten4-Feb-07 6:54 
GeneralRe: Unary Pattern PinmemberGilesb7-Feb-07 1:34 
I realised just after I made the post that the unary operator can be simulated by a binary operator with left had operand of zero.
 

i = (-j) ==> i = (0 - j)
 
Well that works for numbers.
 
Not sure about (-True) shouldn't that return False?
My Immediate window in VS2005 seems to disagree.

QuestionCan It be done with Codedom? Pinmembermbkasi8-Nov-06 15:55 
AnswerRe: Can It be done with Codedom? PinmemberOmer van Kloeten9-Nov-06 1:15 
Generalsuggestion PinmemberSystem.Object17-May-06 3:51 
AnswerRe: suggestion PinmemberOmer van Kloeten17-May-06 9:13 
GeneralRe: suggestion PinmemberSystem.Object17-May-06 9:34 
GeneralRe: suggestion PinmemberOmer van Kloeten17-May-06 9:46 
GeneralRe: suggestion PinmemberEfran Cobisi10-Oct-06 7:07 
AnswerRe: suggestion PinmemberOmer van Kloeten10-Oct-06 8:04 
Generalnullable property Pinmemberjonavi8-May-06 13:10 
AnswerRe: nullable property PinmemberOmer van Kloeten8-May-06 18:41 
Generalspectacular Pinmemberjonavi8-May-06 11:07 
GeneralRe: spectacular PinmemberOmer van Kloeten8-May-06 18:53 
GeneralAdding Region Pinmembervbinfo15-Jan-06 23:11 
AnswerRe: Adding Region PinmemberOmer van Kloeten16-Jan-06 7:22 
GeneralRe: Adding Region Pinmembervbinfo16-Jan-06 7:46 
AnswerRe: Adding Region PinmemberOmer van Kloeten16-Jan-06 8:22 
GeneralExcellent! PinmemberAlexey A. Popov17-Nov-05 22:48 
AnswerRe: Excellent! PinmemberOmer van Kloeten18-Nov-05 1:00 
GeneralDumb question Pinmembersmesser17-Nov-05 6:39 
GeneralRe: Dumb question PinmemberTony Snearly17-Nov-05 7:52 
AnswerRe: Dumb question PinmemberOmer van Kloeten17-Nov-05 9:34 
GeneralRe: Dumb question Pinmembersmesser18-Nov-05 6:23 
GeneralRe: Dumb question PinmemberDevin G5-Dec-05 8:54 
AnswerRe: Dumb question PinmemberOmer van Kloeten5-Dec-05 9:05 
GeneralGreat Idea PinmemberMaruis Marais3-Nov-05 9:46 
QuestionRe: Great Idea PinmemberJeff Firestone7-Feb-06 12:11 
AnswerRe: Adding Assemblies to the Add Reference Dialog Box PinmemberOmer van Kloeten7-Feb-06 21:57 
QuestionRe: Adding Assemblies to the Add Reference Dialog Box PinmemberJeff Firestone8-Feb-06 5:27 
AnswerRe: Adding Assemblies to the Add Reference Dialog Box PinmemberOmer van Kloeten8-Feb-06 8:03 
GeneralRe: Adding Assemblies to the Add Reference Dialog Box PinmemberJeff Firestone8-Feb-06 8:56 
AnswerRe: Adding Assemblies to the Add Reference Dialog Box PinmemberOmer van Kloeten8-Feb-06 9:11 
GeneralVery Nice! Pinmemberjconwell1-Nov-05 9:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 31 Oct 2006
Article Copyright 2005 by Omer van Kloeten
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid