12 posts categorized "Code Snippets"

03/06/2005

Generic Methods

Following my blog about Generic Delegates and Anonymous Methods, here is more:

Generics and anonymous methods can make code a lot more flexible.

Following I show different ways to accumulate the balance of Account objects. The Account class is a simple class that has a Balance property to access the balance of the class.

1. Summarizing the balance of Account objects in a collection can be done with the Accumulate method:

public static decimal Accumulate(IEnumerable e)
{
   decimal sum = 0;
   foreach (Account a in e)
   {
      sum += a.Balance;
   }
   return sum;
}

Invoking the method, the Account collection is passed:

decimal amount = Algorithm.Accumulate(accounts);

2. Making this method generic that it is possible to use other than Account objects, a generic method Accumulate can be implemented. However, because the Balance property is accessed for the accumulation, all generic TAccount classes must offer this property as is defined with the constraint IAccount.  

public static decimal Accumulate<TAccount>(IEnumerable<TAccount> coll)
   where TAccount : IAccount
{
   decimal sum = 0;
   foreach (TAccount obj in coll)
   {
      sum += obj.Balance;
   }
   return sum;
}

Invoking the method is not different to before:

decimal amount = Algorithm.Accumulate(accounts);

3. The second version has the requirement that all objects that are accumulated implement the Balance property. This can be more flexible by defining a generic delegate that defines the action.

Now the Accumulate mehtod can do anything to any object of a collection. What is done to the objects is defined with the delegate Action<>(). This Action delegate defines two parameters and a return type.

public delegate TSum Action<TObj, TSum>(TObj obj, TSum sum);

public static TSum Accumulate<TObj, TSum>(
  
IEnumerable<TObj> coll, Action<TObj, TSum> action)
{
   TSum sum = default(TSum);

   foreach (TObj obj in coll)
   {
      sum = action(obj, sum);
   }
   return sum;
}

To do the same as before - adding all balances - the implementation of the Action can be defined as anonymous method calling the Accumulate method.

decimal amount = Algorithm.Accumulate<Account, decimal>(
   accounts,
   delegate(Account a, decimal sum)
   {
      return a.Balance + sum;
   });

This is really flexible as it is not only possible to use Account objects, but any object. Instead of accumulating some values anything else can be done, too.

Of course anonymous methods should only be used with very simple implementations that are not needed somewhere else. Instead of anonymous methods a normal method can be used, too.

Christian

01/23/2005

Dispose and Finalize with C++/CLI, C# and VB

Depending on the .NET language more or less of implementing resource management with the interface IDisposable and the finalizer is hidden. Interestingly, with VB nothing is hidden - however all the code is created automatically with Visual Studio 2005 as soon as the interface IDisposable is implemented.

The syntax implementing the Dispose method of the IDisposable interface and overriding the Finalize method of the Object class is shown with this table:

IL C++/CLI C# VB
Dispose ~ClassName Dispose Dispose
Finalize !ClassName ~ClassName Finalize

Visual Basic does not hide Dispose and Finalize. The automatically created code (with Visual Studio 2005) also includes the Dispose(bool) pattern:

Public Class Resource
    Implements IDisposable

    Private disposed As Boolean = False

    ' IDisposable
    Private Overloads Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposed Then
            If disposing Then
                ' TODO: put code to dispose managed resources
            End If

            ' TODO: put code to free unmanaged resources here
        End If
        Me.disposed = True
    End Sub

#Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Overloads Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overrides Sub Finalize()
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(False)
        MyBase.Finalize()
    End Sub
#End Region

End Class

Implementing a similar functionality with C#, the destructor syntax is used to override the Finalize method. The IDisposable interface and the Dispose pattern must be implemented traditionally.

class Resource : IDisposable
{
  private bool disposed = false;

  ~Resource()
  {
    Dispose(false);
  }

  protected void Dispose(bool disposing)
  {
    if (disposing)
    {
      // dispose managed resources
    }
    // dispose unmanaged resources

    disposed = true;
  }

  #region IDisposable Members
 
public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
 
#endregion

  public void Foo()
  {
    if (disposed)
      throw new ObjectDisposedException("Object already disposed");
    //...

  }
}

C++/CLI not only hides the implementation of the Finalize method, but also the implementation of the IDisposable interface with the Dispose method. Contrary to C# where the destructor is used to implement the finalizer, here the destructor is used to implement IDisposable. Calling this method is done with the delete operator. The destructor syntax automatically includes code for GC.SuppressFinalize(this).

To override the Finalize method, a new syntax is used: !Class().

The Dispose(bool) pattern still must be done.

ref class Resource
{
private:
  bool disposed;
public:
  Resource()
  {
    disposed = false;
  }

  ~Resource() // IDisposable
  {
    Dispose(true);
  }

protected:
  !Resource() // Finalize
  {
    Dispose(false);
  }

  void Dispose(bool disposing)
  {
    if (disposing)
    {
      // dispose managed resources
    }
    // dispose unmanaged resources

    disposed = true;
  }
};

Christian

01/15/2005

C++/CLI and IDisposable

With my previous post about Instantiating Managed Objects with C++/CLI you could read about using ref types two different ways: with local variables and with a handle.

Now I'm adding implementing the IDisposable interface with the Test class:

ref class Test
{
public:
    ~Test()
    {
        Console::WriteLine("destructor");
    }

    void Foo()
    {
        Console::WriteLine("Inner.Foo");
    }
};

With C++/CLI the IDisposable interface is implemented with the destructor syntax.

Now it would be good to do a try/finally to dispose the object. With C++/CLI the object is disposed using delete.
Test^ t = gcnew Test();
try
{
    t->Foo();
}
finally
{
    delete t;
}

With local variables the same can be done with fewer lines of code. This is shorter than the C# using statement!

Test t;
t.Foo();

The generated code is nearly the same. Nearly as in the first version the IL code uses the IL .try/finally statements, whereas the second version uses IL .try/fault and disposes the object in the fault and the default case.

Christian

01/14/2005

C++/CLI: Instantiating Managed Objects

C++/CLI (not Beta 1) allows declaring reference types as local variables. Let's start with this simple ref class:

ref class Test
{
public:
    void Foo()
    {
        Console::WriteLine("Foo");
    }
};

Handles and the gcnew operator can be used to create instances:
Test^ t = gcnew Test();
t->Foo();

And without using a handle - this looks like a value type (this is new with Visual Studio 2005 versions after Beta 1):
Test t;
t.Foo();

What's the difference with the generated IL code? Nothing! Using a reference type as a local variable creates an object on the heap the same way as the version with the local variable. A reference type is not put on the stack.
A special advantage using local variables is with classes that implement IDisposable as you can read in my next weblog entry.

Christian

09/30/2004

Creating Word Documents with XSLT (Part 2 - Creating Tables)

With my last blog about creating Word documents with XSLT I've shown an example to do a very simple document.

Here I'm showing how to create a table using Word. The same XML file as before is used:

<?xml version="1.0" encoding="utf-8" ?>
<Courses>
 <Course Number="MS-2524">
  <Title>XML Web Services Programming</Title>
 </Course>
 <Course Number="MS-2124">
  <Title>C# Programming</Title>
 </Course>
 <Course Number="NET2">
  <Title>.NET 2.0 Early Adapter</Title>
 </Course>
</Courses>

The XSLT file to create a Word document with a table:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
  <xsl:processing-instruction name="mso-application">
   <xsl:text>progid="Word.Document"</xsl:text>
  </xsl:processing-instruction>
  <w:wordDocument>
   <w:body>
    <w:tbl>
     <w:tblPr>
      <w:tblStyle w:val="TableGrid"/>
      <w:tblW w:w="0" w:type="auto"/>
      <w:tblLook w:val="01E0"/>
     </w:tblPr>
     <w:tblGrid>
      <w:gridCol w:w="4428"/>
      <w:gridCol w:w="4428"/>
     </w:tblGrid>

     <w:tr>
      <w:tc>

       <w:p>
        <w:r>
         <w:t>Number</w:t>
        </w:r>
       </w:p>
      </w:tc>
      <w:tc>

       <w:p>
        <w:r>
         <w:t>Course Title</w:t>
        </w:r>
       </w:p>
      </w:tc>
     </w:tr>

     <xsl:apply-templates select="Courses/Course" />
    </w:tbl>
   </w:body>
  </w:wordDocument>
 </xsl:template>
 <xsl:template match="Course">
  <w:tr>
   <w:tc>
    <w:p>
     <w:r>
      <w:t>
       <xsl:value-of select="@Number" />
      </w:t>
     </w:r>
    </w:p>
   </w:tc>
   <w:tc>
    <w:p>
     <w:r>
      <w:t>
       <xsl:value-of select="Title"/>
      </w:t>
     </w:r>
    </w:p>
   </w:tc>
  </w:tr>
 </xsl:template>
</xsl:stylesheet>

With WordML these are some elements that make up a table:

<tbl> <tbl> represents a table. This is similar to HTML <TABLE>. A WordML <table> element exists, too. However, the <table> element is used for a Office Data Source Object. 
<tblPr> With the element <tblPr> table-wide properties such as the style and the width are defined.
<tblGrid> The element <tblGrid> defines the grid layout of the table. In the example two columns with similar width are defined.
<tr> <tr> is the row of a table
<tc> <tc> is a column inside the row

This helps creating Word documents with WordML:

  • Create a document with Microsoft Word and save it as XML file. Check the XML source.
  • Using Visual Studio 2005, add the Word schemas to the XML file for Intellisense-support.
  • Check the documentation of the Office schemas.

The Office schemas (including documentation) can be found on the MSDN Website.

Christian

09/26/2004

Documentation that shows up in the XML Editor

The XML Editor of Visual Studio 2005 shows the elements that are allowed according to the XML Schema. The editor not only shows the elements and attributes that are possible where the cursor is positioned, it also shows some documentation about the elements and attributes. The documentation can be written inside the schema with the <xsd:annotation> and <xsd:documentation> tags:

  <xs:element name="Book" minOccurs="0" maxOccurs="unbounded">
     <xs:annotation>
      <xs:documentation>Represents information about a book.</xs:documentation>
     </xs:annotation>

     <xs:complexType>
      <xs:sequence>
       <xs:element name="Title" type="xs:string">
        <xs:annotation>
         <xs:documentation>Represents the title of a book.</xs:documentation>
        </xs:annotation>

       </xs:element>
      
<!-- ... -->

Christian

09/25/2004

Creating Word Documents with XSLT

Using the Office Schemas it is easy to create Microsoft Word 2003 documents.

Let's start with this XML document:

<?xml version="1.0" encoding="utf-8" ?>
<Courses>
 <Course Number="MS-2524">
  <Title>XML Web Services Programming</Title>
 </Course>
 <Course Number="MS-2124">
  <Title>C# Programming</Title>
 </Course>
 <Course Number="NET2">
  <Title>.NET 2.0 Early Adopter</Title>
 </Course>
</Courses>

The result should be a Word document.

A simple Word document containing the above data can be as simple as this:

<?xml version="1.0" encoding="utf-8"?>
<?mso-application progid="Word.Document"?>
<w:wordDocument xmlns:w="
http://schemas.microsoft.com/office/word/2003/wordml">
  <w:body>
    <w:p>
      <w:r>
        <w:t>MS-2524, XML Web Services Programming</w:t>
      </w:r>
    </w:p>
    <w:p>
      <w:r>
        <w:t>MS-2124, C# Programming</w:t>
      </w:r>
    </w:p>
    <w:p>
      <w:r>
        <w:t>NET2, .NET 2.0 Early Adopter</w:t>
      </w:r>
    </w:p>
  </w:body>
</w:wordDocument>

With XSLT the document can be created using this style sheet:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
 xmlns:w="
http://schemas.microsoft.com/office/word/2003/wordml">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
  <xsl:processing-instruction name="mso-application">
   <xsl:text>progid="Word.Document"</xsl:text>
  </xsl:processing-instruction>
  <w:wordDocument>
   <w:body>
     <xsl:apply-templates select="Courses/Course" />
   </w:body>
  </w:wordDocument>
 </xsl:template>
 <xsl:template match="Course">
    <w:p>
     <w:r>
      <w:t>
       <xsl:value-of select="@Number" />, <xsl:value-of select="Title"/>
      </w:t>
     </w:r>
    </w:p>
 </xsl:template>
</xsl:stylesheet>

Adding the processing instruction mso-application to the document allows the system to deal with the XML file as a Word document. The parser reads the progid for Word to display the Word icon, and to start Word when opening the file.

  <xsl:processing-instruction name="mso-application">
   <xsl:text>progid="Word.Document"</xsl:text>
  </xsl:processing-instruction>

The elements <w:wordDocument> and <w:body> can be compared to the HTML tags <HTML> and <BODY>. <w:t> is the tag for a text output.

The schemas for Microsoft Office 2003 can be downloaded from the MSDN Website. The download is an installation package that includes schemas for Office 2003 as well as documentation. Referencing the schemas with the XML and XSLT editors of Visual Studio 2005 gives intellisense :-)

Christian

 

09/24/2004

XSLT: Converting multiple elements to one attribute

I've received a question how to convert multiple XML elements to a values for a single attribute. Here is the information about how this can be done with XSLT.

The XML source:

<Article>
 <Head>
  <Title>.NET Enterprise Services</Title>
  <MainCategory></MainCategory>
  <Keyword>Framework</Keyword>
  <Keyword>C#</Keyword>
  <Keyword>Enterprise Services</Keyword>
 </Head>
 <Body>
 </Body>
 <Info>
 </Info>
</Article>

From this source the elements <Keyword> should be converted to this result:

<META name="keywords" content="Framework, C#, Enterprise Services">

This is done with this XSLT transformation:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Demo Style sheet to convert multiple elements to a single attribute value 
-->
<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
    version="1.0">
 <xsl:output method="html" indent="yes"/>
 <xsl:template match="/">
  <HTML>
   <HEAD>
    <xsl:element name="META">
     <xsl:attribute name="name">keywords</xsl:attribute>
     <xsl:attribute name="content">
      <xsl:for-each select="Article/Head/Keyword">
       <xsl:value-of select="."/>
       <xsl:if test="position() != last()">, </xsl:if>
      </xsl:for-each>
     </xsl:attribute>
    </xsl:element>
    <TITLE>
    </TITLE>
   </HEAD>
   <BODY></BODY>
  </HTML>
 </xsl:template>
</xsl:stylesheet>

<xsl:element> and <xsl:attribute> allows dynamic creation of elements and attributes. <xsl:element name="META"> defines the element <META>. <xsl:attribute name="name">keywords</xsl:attribute> results in <META name="keywords">. The content of the attribute content is created dynamically with a selection of each <Article><Head><Keyword> element, and in between of these values a semicolon is added. <xsl:if test=position() != last()"> checks if the <Keyword> element was not the last one, as with the last one no more semicolon is used.

I really like the XSLT editor and debugger of Visual Studio 2005. This makes it easy to create XSLT files.

Update: Bryan has another option to create the Meta tags:

 <xsl:template match="/">
  <HTML>
   <HEAD> 
    <META name="keywords">
     <xsl:attribute name="Content">
      <xsl:apply-templates select="Article/Head/Keyword" />
     </xsl:attribute>
    </META>
    <TITLE>
    </TITLE>
   </HEAD>
   <BODY></BODY>
  </HTML>
 </xsl:template>
 
 <xsl:template match="Article/Head/Keyword" >
  <xsl:value-of select="."/>
  <xsl:if test="following-sibling::Keyword">,</xsl:if>
 </xsl:template>

Christian

05/09/2004

Interface Inheritance

Memi Lavi writes about inherits vs. implements in C#, and that the difference gets much more obvious with VB. He also talks about multiple inheritance with interfaces is not possible.

Mostly I'm writing my programs with C# (sometimes C++ and VB). Now I've done some VB code to see the difference.

Multiple inheritance is possible with interfaces, and VB also uses the Inherits keyword here:

Public Interface IA
    Sub A()
End Interface

Public Interface IB
    Sub B()
End Interface

Public Interface IC
    Inherits IA, IB
    Sub C()
End Interface

Multiple inheritance with interfaces.

With C# it is possible that a class derives from an interface but gets the interface implementation from an abstract base class. The C# code is here:

public interface IA
{
   void A();
}

public abstract class XA
{
   public void A() { }
}

public class X : XA, IA  // get the implementation of IA from XA
{
}

Such a scenario seems not possible with VB. With the Implements keyword of VB, always an implementation is needed.

Of course the code can be changed, so that the abstract class implements the interface.

Christian

10/30/2003

.NET 2.0: Database Independent ADO.NET

.NET 2 has new factories that makes it easier to write data-programs independent of the databsae.

With .NET 1.0, we could program independent of the database using interfaces:

IDbConnection connection = new SqlConnection(connectionString);
IDbCommand command = connection.CreateCommand();
command.CommandText = "select * from customers";
connection.Open();
IDataReader reader = command.ExecuteReader();
while (reader.Read())
{
   //...

The connection object can also be created with the Activator class - to make it independent of the database. What about creating a SqlDataAdapter? This needs to be done similar to the connection. A custom factory class is very useful with 1.0.

.NET 2.0 offers database-independent factory DBProviderFactory:

DbProviderFactory provider = DbProviderFactories.GetFactory ("System.Data.SqlClient");
DbConnection connection = provider.CreateConnection ();
DbDataAdapter adapter = provider.CreateDataAdapter ();

The available providers can be found in the configuration file.

Christian