#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);

#1,204 – C# 6.0 – Using Null-Conditional with Indexer

The new null-conditional operator in C# 6.0 allows checking for null and de-referencing a variable in a single step.

You can use the null-conditional operator with dot (.) notation, to access an object’s properties or to invoke a method.  You can also use the null-conditional with an indexer, as shown below.  The expression returns the value returned by the indexer if the variable is non-null, or returns null if the variable is null.

            string sTest = "Howdy";

            char? thirdChar = sTest?[2];   // 'w'

            sTest = null;
            thirdChar = sTest?[2];   // null

            sTest = "Ho";
            thirdChar = sTest?[2];   // throws IndexOutOfRangeException

Notice that the null-conditional operator protects you from de-referencing a null pointer, but does not protect you from using an index that is longer than the string length.

#1,203 – C# 6.0 – Using the Null-Conditional with Value Types

The new null-conditional allows checking for null and de-referencing a reference-typed variable in a single step.

            string sLeft = sTest?.Substring(0, 1);

If the variable being checked for null (e.g. sTest) is null, the result of the expression is null.  This works as expected if the result of the expression is being assigned to a reference-typed variable (e.g. sLeft).  If the method or property being invoked, however, is a value type, then the result of the expression must be a nullable type.

For example, we might do the following in C# 5.0:

            int sLen;
            if (sTest != null)
                sLen = sTest.Length;

If sTest is null, the assignment isn’t done and sLen retains its value.

In C# 6.0, you can do this assignment using the null-conditional.  The variable being assigned to must be a nullable type whose base type matches the type of the expression.

            int? sLen = sTest?.Length;

#1,202 – C# 6.0 – Null-Conditional Operator

One of the new features coming in C# 6.0 is the null-conditional operator.

If you have a reference-typed variable, it can have a null value or can refer to instance of the appropriate type.  You’ll often see the following pattern, checking for null before invoking a method on the object, to avoid a NullReferenceException.

            string sTest = DateTime.Now.Hour == 5 ? "Five" : null;

            // OLD: Check for null to avoid NullReferenceException
            string sLeft;
            if (sTest != null)
                sLeft = sTest.Substring(0, 1);

The null-conditional operator allows us to do the same check for null, but in a more concise manner.

            // NEW: Null-Conditional operator
            sLeft = sTest?.Substring(0, 1);

If sTest is non-null, the Substring method is called and the result is assigned to sLeft.  If sTest is null, the expression returns null, so a null value is assigned to sLeft.

Follow

Get every new post delivered to your Inbox.

Join 477 other followers