Sample code in C#

In my mind, C# and .NET meld together. Now that .NET is for real, I think that C# is the language of choice for programmers who know C++ and/or Java.

Not that the .NET Framework hasn't turned out to be a mixed blessing. It is big, slow, and ugly in ways that only Microsoft could have invented. And Microsoft's notions of how to connect an interactive software application to a database are weirder than ever.

But .NET manages types much better than COM (remember COM?), and I find C#'s syntax to be cleaner than that of C++ or VB for writing code that takes advantage of .NET's type system. For that matter, C# also strikes me as being easier to use for code that deals with delegates, events, and other programming constructs that did not even exist when Basic and C++ were invented.

Anyway, this bit of C# sample code is extracted from an implementation of a subclass for the .NET PictureBox control. This particular event handler executes whenever something changes the Image object contained in the control. The handler updates a row in a data table with the raw image data so that it can be subsequently shipped to the table's underlying data source (which is most likely a database).

protected virtual void OnImageChanged( EventArgs e )
{
    DataRow rw;

    // fire this event
    if( m_fnImageChanged != null )
        m_fnImageChanged.Invoke( this, e );

    // do nothing if there is no data binding
    if( m_tblImg == null )
        return;

    // if the table is empty or if there is no current position, add a new row
    if( (m_tblImg.Rows.Count == 0) || (m_CurrencyMgr.Position < 0) )
    {
        // add the row to the table
        rw = m_tblImg.NewRow();
        m_tblImg.Rows.Add( rw );

        // set the new position
        m_CurrencyMgr.Position = m_CurrencyMgr.Count - 1;
    }

    else
        rw = ((DataRowView)m_CurrencyMgr.Current).Row;

    // store a reference to the Image data in the row
    if( base.Image != null )
    {
        // create a MemoryStream object into which the image data will be copied
        System.IO.MemoryStream strm = new System.IO.MemoryStream( 0 );

        // copy the image data into the MemoryStream object
        base.Image.Save( strm, base.Image.RawFormat );

        /* set MemoryStream.Capacity to the exact size of the data

            The MemoryStream buffer is allocated in chunks, so the Capacity is
            virtually certain to be larger than the actual data length.  Setting
            the Capacity property to match the actual data length causes the
            subsequent call to GetBuffer to return a buffer whose size is the
            same as the amount of data.
        */
        strm.Capacity = Convert.ToInt32( strm.Length );
        strm.Close();

        // copy a reference to the Image data into the row
        rw[this.DisplayColumn] = strm.GetBuffer();
    }

    else    // (null Image)
        rw[this.DisplayColumn] = System.DBNull.Value;
}
    

Some comments on the code

This code illustrates how much functionality is implicit in the underlying .NET Framework, to the point where application code sometimes resembles a script that does little besides make calls into the Framework.

The field m_tblImg (yes, it is hard to lose those C++ member-variable naming habits) is a reference to an underlying data table. The object's DisplayColumn property is a reference to the column in the table that is updated when the Image data changes. The m_CurrencyMgr field references an object that tracks the current position in a list (in this case, a row in the data table).

One reason this code is so straightforward is that the .NET Image object hides its underlying format (JPEG, GIF, BMP, etc.), so one subclass implementation works for all of the image formats known to the Image object.

This page updated Friday, October 21, 2005 at 23:49 UTC.

This page is valid XHTML and uses valid CSS.