#1,211 – C# 6.0 – Adding Implementation for a Primary Constructor

NOTE: Primary constructors will not be shipping in C# 6.0, after all.  They were implemented in the language, but did not yet have appropriate downstream work done in time for the release of 6.0 (i.e. in Visual Studio and debugger).  Thanks to Steve Hall for pointing this out.  –SPS, 23Oct14

A primary constructor in C# 6.0 allows declaring constructor parameters as part of the type declaration and then using those parameters within auto-property initializers.

You can optionally include an implementation body for the primary constructor, typically at the start of the type.  The implementation includes a code block without any method name or parameters.

Below, the primary constructor implementation derives the value of one property from the name parameter and does some validation on the age parameter.

    public class Dog(string name, int age)
    {
        {
            Name = name + " the Dog";
            if (age > 20)
                throw new ArgumentException("Age too large");
        }

        public string OrigName { get; } = name;
        public string Name { get; protected set; }
        public int Age { get; set; } = age;
    }

1211-001

#1,210 – C# 6.0 – Primary Constructors

NOTE: Primary constructors will not be shipping in C# 6.0, after all.  They were implemented in the language, but did not yet have appropriate downstream work done in time for the release of 6.0 (i.e. in Visual Studio and debugger).  Thanks to Steve Hall for pointing this out.  –SPS, 23Oct14

C# 6.0 introduces the notion of a primary constructor–a constructor defined as part of the type declaration, rather than as a separate method.

Consider the C# 5.0 example below, with a traditional constructor that initializes a couple of properties.  (Note that Name property is not immutable, but only protected).

    public class Dog
    {
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public string Name { get; protected set; }
        public int Age { get; set; }
    }

The primary constructor syntax allows us to simplify this code, moving the constructor into the class declaration.  We can then use auto-property initializers that reference the constructor’s parameters.

    public class Dog(string name, int age)
    {
        public string Name { get; protected set; } = name;
        public int Age { get; set; } = age;
    }

This second code fragment behaves exactly like the first.

#1,209 – C# 6.0 – Using the nameof Operator

C# 6.0 adds a nameof operator that accepts the name of some program element and returns a string representing the name of the element.  The nameof operator can take as a parameter:

  • Class names
  • Class members
  • Method names
  • Variables

Below, the ShowoffNameof method reports the names of various program elements within the Dog class.  This avoids having to explicitly use reflection to access the names of things.

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
        }

        public string ShowoffNameof(int myInteger, string myString)
        {
            StringBuilder sbOut = new StringBuilder();

            sbOut.AppendLine(string.Format("Class: {0}", nameof(Dog)));
            sbOut.AppendLine(string.Format("Method: {0}", nameof(ShowoffNameof)));
            sbOut.AppendLine(string.Format("Name prop: {0}", nameof(Name)));
            sbOut.AppendLine(string.Format("1st param: {0}", nameof(myInteger)));
            sbOut.AppendLine(string.Format("2nd param: {0}", nameof(myString)));
            sbOut.AppendLine(string.Format("Local variable: {0}", nameof(sbOut)));

            return sbOut.ToString();
        }
    }

Here’s the output:
1209-001

#1,208 – C# 6.0 – Auto-Property Initializers Can Be Any Expression

An auto-property initializer, used to initialize the value of an auto-implemented property, can be any expression.  This includes the result of a method call.

Below, we initialize the value of the SecretName property to a value returned by the static function generateSecreteName.

    public class Dog
    {
        public string Name { get; set; }

        // DogCreationTime is immutable
        public DateTime DogCreationTime { get; } = DateTime.Now;

        public string SecretName { get; } = generateSecretName();

        public Dog(string name)
        {
            Name = name;
        }

        private static string generateSecretName()
        {
            Random rand = new Random();
            int numLetters = rand.Next(4, 13);  // 4-12 characters
            string name = "";
            for (int i = 1; i <= numLetters; i++)
                name = name + (char)('a' + rand.Next(0, 26));

            return name;
        }
    }

#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties

Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d typically use a read-only backing field that is initialized in the constructor, as shown below.

    public class Dog 
    {
        public string Name { get; set; }

        // DogCreationTime is immutable
        private readonly DateTime creTime;
        public DateTime DogCreationTime 
        {
            get { return creTime; }
        }

        public Dog(string name)
        {
            Name = name;
            creTime = DateTime.Now;
        }
    }

In C# 6.0, you can use auto-implemented properties to implement a read-only property.  You do this by using an auto-property initializer.  The result is much cleaner than the above example, where we had to explicitly declare a backing field.

    public class Dog
    {
        public string Name { get; set; }

        // DogCreationTime is immutable
        public DateTime DogCreationTime { get; } = DateTime.Now;

        public Dog(string name)
        {
            Name = name;
        }
    }

#1,206 – C# 6.0 – Auto-Property Initializers

C# 3.0 introduced auto-implemented properties.

Older syntax:

private string name = "default";
public string Name
{
    get { return name; }
    set { name = value; }
}

Improved syntax, using auto-implemented properties:

public string Name { get; set; }

The new syntax provided no mechanism for specifying a default property value. To specify a default value, you either needed to go back to using an explicit backing variable or to set the default value from within a constructor.

C# 6.0 supports specifying default values for auto-implemented properties, as shown below.

        public string Name { get; set; } = "default";

#1,205 – C# 6.0 – Using the Null-Conditional when Invoking a Delegate

When you fire an event (by invoking a delegate), you typically need to check for null before invocation.  This avoids a null reference exception if there are no subscribers to the event.

    public class Dog
    {
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public event EventHandler<string> NameChange;

        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                if (value != name)
                {
                    name = value;

                    // Check for null before invocation
                    if (NameChange != null)
                    {
                        NameChange(this, name);
                    }
                }
            }
        }

        public int Age { get; set; }
    }

(The above pattern is not thread-safe).

An alternative pattern is to declare the event with a null handler, so that there is always at least one handler on the invocation list. (This is thread-safe).

In C# 6.0, we can use the null-conditional to invoke a delegate.

                    NameChange?.Invoke(this, name);
Follow

Get every new post delivered to your Inbox.

Join 479 other followers