Tag: C# 6

C# 6

C# 6 Features – Nameof Expressions

Name BadgeIn the latest post on my series about C# 6’s features, I want to look at nameof expressions. There are times when you need the string value of variables or methods or classes in your code. That could be to return an argument exception, it could be to have some sort of property changed notification, or it could even be to get the string value of an enumeration value.

Previously, you had to either have “magic strings” in your application or any number of tricks to abstract away what are basically the magic strings. If you changed the name of a variable, parameter, method, class, or enum, nothing would ensure that you went back and updated your “magic strings”. Perhaps if you had written very finely-grained unit tests (and you remembered to update those when you changed a variable name), you might get a warning, but that is a tremendous amount of discipline. That’s where C# 6 is here to save our bacon.

As an example, here is something we might have done previously

public void Useless(string foo)
{
    if (string.IsNullOrEmpty(foo))
    {
        throw new ArgumentNullException("foo");
    }
    
    return;
}

You can see how I could change the parameter name from foo to something else and the compiler won’t care if I fix the call to ArgumentNullException() or not. However, nameof fixes and prevents that.

public void Useless(string foo)
{
    if (string.IsNullOrEmpty(foo))
    {
        throw new ArgumentNullException(nameof(foo));
    }
    
    return;
}

The benefit here is that if I change the parameter and forget to change nameof(foo) like this:

public void Useless(string bar)
{
    if (string.IsNullOrEmpty(bar))
    {
        throw new ArgumentNullException(nameof(foo));
    }
    
    return;
}

You actually will get a compile time error that says “The name ‘foo’ does not exist in the current context”. Some people hate using the compiler as a unit test, but I don’t. It is basically “round one” of testing. I think the issue arises when it is the the only means of testing used, but it is just another tool in the toolbox that we should use.

As I mentioned earlier, you can use it to get the names of classes, methods, and it lets you stop the SomeEnum.SomeValue.ToString() madness. It is the same syntax and would look like this


public class UselessClass
{
    enum UselessEnum
    {
        UselessEnumValue
    }
    
    public void UselessMethod(string uselessParam)
    {
        Console.WriteLine(nameof(UselessClass));
        Console.WriteLine(nameof(UselessMethod));
        Console.WriteLine(nameof(uselessParam));
        Console.WriteLine(nameof(UselessEnum));
        Console.WriteLine(nameof(UselessEnum.UselessEnumValue));
    }
}

// Later when called...
var uselessObject = new UselessClass();
uselessObject.UselessMethod("uselessValue");

// Outputs these values
/*
UselessClass
UselessMethod
uselessParam
UselessEnum
UselessEnumValue
*/

As I said at the beginning of this series, much of C# 6’s features aren’t mind-blowing, but instead are small improvements to help smooth out some edges. Are you using nameof? Are you going to when you get the chance?

C# 6

C# 6 Features – Using Static

StaticFor this next post in my series on the new features in C# 6, I’m going to cover the using static syntax. This feature is also 100% syntactic sugar, but it can be helpful. Unfortunately, it also comes with quite a few gotchas.

I’m sure all of us are familiar with writing code like you see below. The WriteLine() method is a static method on the static class Console.

using System;

namespace CodeSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World");
        }
    }
}

Because Console is a static class, we can treat it as a “given” and just now include it in our using statements. Console.WriteLine() is actually System.Console.WriteLine() if we include the namespace. However, since we are including “using System;” at the top of the file, we don’t have to type it out. This is the exact same concept.

using static System.Console;

namespace CodeSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine("Hello World");
        }
    }
}

Now instead of just “using”, I’ve included “using static” and included the full name of the static class, in this case System.Console. Once that is done, I’m free to just call the WriteLine() method as if it were locally scoped inside my class. This is all just really syntatic sugar. When I use Telerik’s JustDecompile to analyze the program and give me back the source, this is what I get.

using System;

namespace CodeSandbox
{
    internal class Program
    {
        public Program()
        {
        }

        private static void Main(string[] args)
        {
            Console.WriteLine("Hello World");
        }
    }
}

If we dig even further into the IL, you can see that it agrees that we are still just making a call to WriteLine() inside of the System.Console class.

.method private hidebysig static void Main (
            string[] args
        ) cil managed 
    {
        .entrypoint
        IL_0000: nop
        IL_0001: ldstr "Hello World"
        IL_0006: call void [mscorlib]System.Console::WriteLine(string)
        IL_000b: nop
        IL_000c: ret
    }

Okay, that makes sense. Seems potentially helpful. Where do these promised “gotchas” come in? Our issues start to arise when you have multiple “using static” declarations in a file. If those static classes have methods inside them with the same name, conflicts can happen. Let’s take a look at one place where this can absolutely happen in a commonly used area of .Net.

using System.IO;

namespace CodeSandbox
{
    class Program
    {
        static string fakeSourceLocation = @"c:\";
        static string fakeBackupLocation = @"c:\backup\";

        static void Main(string[] args)
        {
            foreach (var fileWithPath in Directory.GetFiles(fakeSourceLocation))
            {
                var fileName = Path.GetFileName(fileWithPath);
                var backupFileWithPath = Path.Combine(fakeBackupLocation, fileName);

                if (!File.Exists(backupFileWithPath))
                {
                    File.Copy(fileWithPath, backupFileWithPath);
                }
            }
        }
    }
}

In this simple contrived example, I’m iterating through all of the files in a directory and if they don’t exist in a backup location, I copy them there. This doesn’t deal with versioning, etc, but it does give us some basic System.IO examples to work with. Now, if I try to simplify the code like this, I get an issue.

using static System.IO.Directory;
using static System.IO.File;
using static System.IO.Path;

namespace CodeSandbox
{
    class Program
    {
        static string fakeSourceLocation = @"c:\";
        static string fakeBackupLocation = @"c:\backup\";

        static void Main(string[] args)
        {
            foreach (var fileWithPath in GetFiles(fakeSourceLocation))
            {
                var fileName = GetFileName(fileWithPath);
                var backupFileWithPath = Combine(fakeBackupLocation, fileName);

                if (!Exists(backupFileWithPath))
                {
                    Copy(fileWithPath, backupFileWithPath);
                }
            }
        }
    }
}

This won’t even build. Can you guess why? If you are very familiar with System.IO classes, you might have noticed that there is a System.IO.File.Exists() and a System.IO.Directory.Exists(). Our build error lets us know by saying, “The call is ambiguous between the following methods or properties: ‘Directory.Exists(string)’ and ‘File.Exists(string)'”. One way to get around this is to just be explicit at the ambiguous part like this:

using static System.IO.Directory;
using static System.IO.File;
using static System.IO.Path;

namespace CodeSandbox
{
    class Program
    {
        static string fakeSourceLocation = @"c:\";
        static string fakeBackupLocation = @"c:\backup\";

        static void Main(string[] args)
        {
            foreach (var fileWithPath in GetFiles(fakeSourceLocation))
            {
                var fileName = GetFileName(fileWithPath);
                var backupFileWithPath = Combine(fakeBackupLocation, fileName);

                if (!System.IO.File.Exists(backupFileWithPath))
                {
                    Copy(fileWithPath, backupFileWithPath);
                }
            }
        }
    }
}

I don’t know how that makes me feel. It seems like at least a small code smell. Maybe in these occasions, you don’t use this shortcut if it feels wrong. In general, I could see this being like the Great Var Debate of 2008™. People thought that var foo = new Bar(); was smelly compared to Bar foo = new Bar();, but it seems like most people have moved past it. Maybe I’m just on the beginning of this wave of change and I’ll stop yelling for the kids to get off of my lawn soon. At the moment, however, I’m probably going to file using static in the “not something I’m going to really use” pile.

C# 6

C# 6 Features – String Interpolation

For this post in my series, I want to look at one of my favorite little time savers, String Interpolation. String Interpolation is basically when you put tokens into a string and those are replaced for you by the language. Previously, in C#, we might do one of the following things:

// Concatenation
var name = "Pete";
var greeting = "Hello, " + name;
// String Format
var name = "Pete";
var greeting = string.Format("Hello, {0}", name);

Sometimes, with a long string with a lot of tokens, this can get kind of unwieldy. And, if you reuse tokens (say, a line break, or the person’s name), it can be almost impossible to keep things straight. Other languages have had features like this for awhile.

Swift:

var name = "Pete"
var greeting = "Hello, \(name)"

Ruby:

name = "Pete"
greeting = "Hello #{name}"

Now, in C# 6, we get that kind of clarity as well. The syntax calls for you to use a dollar sign ($) in front of the string and then use curly braces surrounding the variable reference in the string. Here is an example

New C# 6 String Interpolation:

var name = "Pete";
var greeting = $"Hello, {name}";

In my opinion, that beats the pants off of string.Format(). Additionally, you can also reference class properties by the same syntax. Here is another example:

var name = "Pete";
var greeting = $"Hello, {name}.  Your name has {name.Length} letters.";

You can also express values from methods:

var items = new []{"a", "b", "c"};
Console.WriteLine($"Items has {items.Count()} items");

So, there you go. I can promise you that I’m going to use this instead of string.Format() in every project that is running the necessary framework versions.

C# 6

C# 6 Features – Expression-bodied Members

I have finally gotten around to looking into C# 6. It was released in July 2015 and available starting in .Net Framework 4.6, but I just hadn’t had any occasion to use it. In order to “force myself” to dig into it a little more, I decided to write a series of blog posts about the new features. The first one out of the gate is Expression-bodied Members.

Expression-bodied Members are just a syntactic sugar on the language. I’m not angry about things that are syntactic sugar. In fact, one of my favorite things about C# 3 was automatic properties, so I’m all in. In reality, it is just about expressing intent more clearly and more succinctly. Here is a very simple example of a method that uses this new feature.

public int DoubleANumber (int input) => input*2;

In this case, I’ve defined a public method that takes an integer and returns an integer. As we are reading left-to-right, there is nothing weird yet. However, after the method name declaration, we change it up and throw the “Anders Operator” aka “Hash Rocket” aka “LINQ Symbol” aka “Goes To” aka “=>” into the mess. Just like LINQ, you can put an expression right afterwards and that is what is evaluated. We are missing the curly braces, sure, but we are also missing a return statement. You don’t need it.

You can also use this simple syntax for properties. Take a look at the following class:

public class Person
{
     public string FirstName {get;set;}
     public string LastName {get;set;}
     
     public string FullName => string.Format("{0} {1}", FirstName, LastName);
}

The FullName property is now just a read-only expression. The alternative would have looked like this:

public class Person
{
     public string FirstName {get;set;}
     public string LastName {get;set;}
     
     public string FullName 
     {
          get { return string.Format("{0} {1}", FirstName, LastName); }
     }
}

Even if you one-lined the FullName property, it would not be as clean as the Expression-bodied version

public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } }

Fantastic. We’ve seen a way to clean up our code a bit, no down side, right? Well, of course there is a down side. This is only really useful and clean-looking if you have a very simple one-liner to express. If you ramp this guy up a bit, it starts to break down.

// DOES NOT COMPILE
public class Ugh
{
    public int DoLotsOfStuff(int input) =>
        input += 2;
        input = input * 2;
        Math.Pow(input, 2);
}

This doesn’t even compile, for probably very obvious reasons. You can’t do a bunch of work on separate lines and then just hope the last evaluation is what is returned. The error you get is “Invalid token ‘=’ in class, struct, or interface member declaration”. The reason being that C# thinks that the method is just public int DoLotsOfStuff(int input) => input += 2; After that, it is trying to figure out how input = input * 2; makes sense as a free standing line within the class. That isn’t how you declare a method, a property, or a field, so C# freaks out. Of course you could jam all of that on one line, but it may start to get confusing the more you try to do.

So, Expression-bodied Members can be a nice clean way to express your code simply. However, the danger here is that developers could try to play “code golf” to get their code to fit on one line. That would really decrease readability, which defeats the entire purpose. So, I feel like this is a feature to use carefully and sparingly.