New XAG Feature: Support for C# 3.0 Automatic Properties

One of the nicest features of C# 3.0 is one of the most subtle: automatic properties.  It's really nothing more than syntactical sugar and saves us a little bit of typing, but it's been a big help in making my code more self-documenting.  If you're unfamiliar with automatic properties, here is what one looks like:

public Int32 Id { get; set; }

When that single line is compiled and viewed in Reflector, you get the following:

[CompilerGenerated]
private int <Id>k__BackingField;

public int Id
{
    [CompilerGenerated]
    get
    {
        return this.<Id>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<Id>k__BackingField = value;
    }
}

The new syntax is equivalent to a classic C# property.  Note that this property has a get accessor and a set accessor.  This is the only type of automatic property you will be able to create.  You need the full {get; set; } for the automatic property to compile.  { get; } or { set; } won't cut it.  If you need a property with only a get or set accessor, then you need to use a classic C# property.  However, you can use { get; private set; } for a read-only property.  It will create both accessors, but only the get accessor will be public.  Also keep in mind that the Visual Studio 2008 code-snippet shortcut "prop" now creates an automatic property and "propg" creates an automatic property with a private set accessor.

Since this feature helps so greatly in the readability of the code, I have added a new feature to XAG: minimized properties.  Here is what the classical C# 2.0 syntax would look like for simple DTO (data transfer object) using XAG:

<Assembly xmlns:x="http://www.jampadtechnology.com/xag/2006/11/">
    <SimpleType x:Key="ClassKey" Type="Class" AutoGenerateConstructorsByProperties="True" Namespace="ClassNamespace"  AccessModifier="Public">
        <Properties AccessModifier="Public">
            <Id Type="Int32" />
            <Name Type="String" />
            <Title Type="String" />
        </Properties>
    </SimpleType>
</Assembly>

Using XAG's express type creation, the XML compiles to the following C# code:

using System;

namespace ClassNamespace
{
    public class SimpleType
    {
        private Int32 id;
        private String name;
        private String title;
        public Int32 Id {
            get { return id; }
            set { id = value; }
        }

        public String Name {
            get { return name; }
            set { name = value; }
        }

        public String Title {
            get { return title; }
            set { title = value; }
        }

        public SimpleType(Int32 id, String name, String title) {
            this.Id = id;
            this.Name = name;
            this.Title = title;
        }

        public SimpleType( ) {
        }
    }
}

That's painfully verbose when compared with automatic properties.  The new feature in XAG allows you to choose between a classic property and a minimized property (an automatic property in C# 3.0).  Below is the same XAG DTO done with Minimized properties.  In this example, notice that AutoGenerateConstructorsByProperties is set to false (the default).  This is because C# 3.0 has feature called object initializers, which allow you to set properties when you instantiate an object without needing any special constructor.

<Assembly xmlns:x="http://www.jampadtechnology.com/xag/2006/11/">
  <SimpleType x:Key="ClassKey" Type="Class" Namespace="ClassNamespace" AccessModifier="Public">
    <Properties AccessModifier="Public" Minimized="True">
      <Id Type="Int32" />
      <Name Type="String" />
      <Title Type="String" />
    </Properties>
  </SimpleType>
</Assembly>

By simply setting Minimized to true (and optionally, AutoGenerateConstructorsByProperties to false), you get the following C# 3.0 code:

using System;

namespace ClassNamespace
{
    public class SimpleType
    {
        public Int32 Id { get; set; }
        public String Name { get; set; }
        public String Title { get; set; }

        public SimpleType( ) {
        }
    }
}

You can also use this new minimize option with the existing options Static (a Boolean) and Mode (Blank, "GetOnly", or "SetOnly"), but you obviously can't use it with the Backing option.   The Backing option has a default value of true which means that the property is backed by a private field.  There is no such thing as an automatic property with an explicit backing field; that's the entire point of an automatic property.  The following example demonstrates a few legal combinations for properties in XAG.  Notice that you can tell XAG that you want all but a few specified properties to be minimized.

<Assembly xmlns:x="http://www.jampadtechnology.com/xag/2006/11/">
    <SimpleType x:Key="ClassKey" Type="Class" Namespace="ClassNamespace"  AccessModifier="Public">
        <Properties AccessModifier="Public" Minimized="True">
            <Id Type="Int32" />
            <Name Type="String" Static="true" Mode="GetOnly" />
            <Title Type="String" Minimized="False" Backing="False" Mode="GetOnly" />
        </Properties>
    </SimpleType>
</Assembly>

This XML code compiles to the following C# 3.0 class:

using System;

namespace ClassNamespace
{
    public class SimpleType
    {
        public Int32 Id { get; set; }

        public static String Name { get; private set; }

        public String Title {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public SimpleType( ) {
        }
    }
}

In C# 3.0, you could use that code with an object initializer like this:

SimpleType st = new SimpleType( )
{
    Id = 8
};

Int32 id = st.Id; // id == 8

You can find more information about my XML Assembly Compiler at http://www.jampadtechnology.com/xag/.

Related Links