MichaelvdV@Atos

Exploring lesser known C# Language features Part II

Blog Post created by MichaelvdV@Atos on Jul 4, 2011

In the first part of this series we discussed the 'yield' keyword, and we learned about 'lazy' and 'eager' evaluation. In this part we continue with some of the lesser known C# language features. Like mentioned in the first post, its sometimes difficult to determine what featurers are really 'lesser known', as this is different for every developer. In this post we are looking at several language features, so I'm sure there's something for everyone!

 

Inline if statement (:? operator)

 

The inline if operator is a ternary operator (it uses 3 'arguments', and creates one result). The inline if operator is a conditional operator that can be used as a single expression.

 

Let's take a look at the 'regular' if statement:

 
string state = "NOT DEFINED";

if (GetValue() > 10)
  state = "High";
else
  state = "Low";

To give an example, you can use the inline if operator to get the same result with less code:

 
string state = GetValue() > 10 ? "Hight : "Low"

 If we compare the grammer of the two:

 
//'Normal' if statement
if (boolean expression)
  true expression
else
  false expression

//Inline if statement
boolean expression ? true expression : false expression
Using normal if statements, we can nest several statements:
if (condition1)
  action1
else if (condition2)
    action2
  else if (condition3)
     action3
  else
     action4

 
We can do the same with the inline if operator:
var value = condition1 ? action1
                 : condition2 ? action2
                 : condition3 ? action3
                 : action4

 It get's really interesting if you think of the inline if operator as just another expression, much like '10 + 10' or '"Hello" + "World"'. Here are some examples how you can use the inline if operator, to shorten your code, and make it much easier to read:

 
var useFirstServer = true;
            var server = new PISDK.PISDK().Servers[useFirstServer ? "firstServer" : "secondServer"];

            var number = 10;
            var elem = new AFElement(number < 10 ? "LowNumberElement" : "HighNumberElement");

            var day = "yesterday";
            var value = new AFValue(100, day == "today" ? DateTime.Today : DateTime.Today.AddDays(-1));

 

 

 

 

The ?? operator (null-coalescing)

 

One of the things we as programmers have to do all to often, is check for null values. You can never trust user input, or know if a calculation produced a null result. A simple example would be this:

 
  public void SchrodingersCat()
        {
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

            string stateText = string.Empty;
            if (state != null)
                stateText = state.ToString();
            else
                stateText = "NOTHING";

            Console.WriteLine(stateText);
        }

 

 

We cannot know what 'state' will be until we check it. It can be either null or a string. In this case, we use an if statement to check wheter state is null. We can also do it shorter with the inline if statement we discussed earlier in this article.

 
 public void SchrodingersCat()
        {
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

          
            Console.WriteLine(state != null ? state.ToString() : "NOTHING");
        }

 

 

 

 

Here we use the inline if statement to check for a null value. As you can see we don't need any intermediary variables. This is already really short. But, C# provides us with an ever shorter way: the null-coalescing operator (or ??).

 

The grammer of the ?? operator is:

 

possiblyNullValue ?? valueIfNull

 

So, if we want to use it in this case:

 

 

 
  public void SchrodingersCat()
        {
            //Create a new random generator
            var random = new Random();
            //Create an array with objects and nulls
            var stateArray = new object[] { "Hello world!" , null, "Hello Again!", null };
            //Get a state using a random generated index
            var state = stateArray[random.Next(stateArray.Length -1)];

            //We don't know what 'state' will be, it can be an object or a null

          
            Console.WriteLine(state ?? "NOTHING");
        }

 

 

 

 

That's even shorter! And it produces again less code. In this case it also improves readability, once you are used to using the ?? operator.

 

The 'using' statement

 

The term 'using' has two distinct functions within C#. We all use the 'using' directive everytime we create a new application.

 

The using directive let's us 'import' a namespace, so that we can use the types of that namespace without having to use the full typename. For example:

 
using System.Xml.Linq;
using OSIsoft.AF.Asset;

 

 

This is something we use everyday. The 'using statement' has a totally different function.

 

We can use the using statement to define a scope. Outside of this scope, the objects will be disposed. Objects that implement the IDisposable interface deal with unmanaged code. This means, they have unmanaged pointers or handlers that cannot be controlled (or freed) by the Garbage Collector of .NET. The IDisposable interface has only one method, the 'Dispose' method. This happens when you are for instance dealing with the filesystem, or certain network related objects.

 

For example, let's say we want to make use of a MemoryStream, and ensure that all the (unmanaged) handlers are freed successfully after use. We can use the following code:

 
  var text = "Hello world!";
            var buffer = Encoding.ASCII.GetBytes(text);
            var stream = new MemoryStream(buffer);

            //Do something with the stream

            stream.Dispose();

            //Stream is still accessable here, but it is already disposed. We will get Exceptions when we try
            //to access it after the Dispose method is called

 

 

We call the 'Dispose' method after we are done dealing with the MemoryStream. The issue here is that the 'stream' variable will still be in scope (accessable) after we have called the 'Dispose' method. Once you have called the 'Dispose' method, the underlying resources are freed. You will get an Exception if you would try to use stream.Peek().

 

There is a better, nicer and safer way to ensure proper disposal. This is done with the 'using' statement.

 
var text = "Hello world!";
var buffer = Encoding.ASCII.GetBytes(text);
using (var stream = new MemoryStream(buffer))
{
      //Do something with the stream
}
//stream will be out of scope here

 

 

In this case, we are creating a new memorystream from a byte[] array. We can use the stream inside the using block. The variable will be out of scope after the using block, and it will automatically call the 'Dispose' method of the MemoryStream. This is a much safer way than manually having to call 'dispose'. Offcourse, you can 'nest' using statements, which creates really clean code:

 
var text = "Hello world!";
            var buffer = Encoding.ASCII.GetBytes(text);
            using (var stream = new MemoryStream(buffer))
            using (var streamReader = new StreamReader(stream))
            using (var streamWriter = new StreamWriter(stream))
            {
                //Do something with the stream, streamReader and streamWriter
            }
            //stream, streamReader, streamWriter are out of scope now

 

 

Summary

 

In this article we described the usage of the 'inline if' operator, or ?: operator. It can help you produce cleaner and lesser code. We also learned about the null-coalescing operator, or the ?? operator. It is a very short way of doing null checks in a single statement.

 

The 'using statement', not to be confused with the 'using directive' allows us to create safe and clean code when dealing with unmanaged resources.

 

Further reads

 

The :? operator (MSDN)

 

The ?? operator (MSDN)

 

The using statement (MSDN)

 

The using directive (MSDN)

 

The IDisposable interface (MSDN)

 

IDisposable: What your mother never told you about resource deallocation (CodeProject)

 

 

 

Previous articles in this series

 

Exploring lesser known C# Language features Part I (the 'yield' statement)

 

 

 

 

Outcomes