browse by category or date

I have completed viewing this talk titled “Change your habits: Modern techniques for modern C#” by Bill Wagner (TIL: Bill authored Effective C#). I list down below, all that I have learned from this talk. You can watch the full video at the end of this post (with privacy enabled).

1. Using Tuples in Constructor

Assume we have a Point struct:

public struct Point
{
    public double X
    {
        get;
        private set;
    }

    public double Y
    {
        get;
        private set;
    }

    private double? distance;
    public double Distance
    {
        get
        {
            if (!distance.HasValue)
                distance = Math.Sqrt(X * X + Y * Y);
            return distance.Value;
        }
    }

    public Point(double x, double y)
    {
        X = x;
        Y = y;
        distance = default; // default only available in C# 7.1
    }
}

Instead of this constructor:

    public Point(double x, double y)
    {
        X = x;
        Y = y;
        distance = default; // default is only available in C# 7.1
    }

We use:

public Point(int x, int y) => 
   (this.x, this.y, this.distance) = (x, y, default);

2. Tuples in Operator Overloading

We are still in the Point struct context. Instead of:

public static operator ==(Point left, Point right) =>
   left.x == right.x && left.y == right.y;

public static operator !=(Point left, Point right) =>
   left.x != right.x || left.y != right.y;

Use

public static operator !=(Point left, Point right) =>
   (left.x, left.y) != (right.x, right.y);

3. Using Tuples to Swap Values

Remember that interview question where you supposed to swap two values without introducing a third variable? Tuples can easily help you do that. Bill’s sample below is to swap the X,Y coordinates of Point struct.

public void SwapCoords() => 
   (X,Y) = (Y,X);

Based on above example, I created below to help me understand Tuples more.

static void Main(string[] args)
{            
    var originalTuple = (10, 20);
    var swappedTuple = SwapValue(originalTuple);
    Console.WriteLine("Original:" + originalTuple); // Original:(10, 20)
    Console.WriteLine("Swapped:" + swappedTuple); // Swapped:(20, 10)
    Console.ReadLine();
}

public static (int, int) SwapValue((int, int) t) => (t.Item2, t.Item1);

4. Immutable Struct Using Readonly

Below is the completely immutable Point struct

public readonly struct Point
{
    public double X
    {
        get;
    }

    public double Y
    {
        get;
    }

    public double Distance
    {
        get;        
    }

    public Point(double x, double y) =>
        (X, Y, Distance) = (x, y, Math.Sqrt(x * x + y * y));
}

5. Throw ArgumentNullException on null parameter

Below is a Person class which will throw ArgumentNullException upon null parameter. The example also using new keyword nameof, which was introduced in C# 6.0.

public class Person
{
    private string _firstName;
    private string _lastName;
    public string FirstName
    {
        get => _firstName;
        set => 
            _firstName = value ?? 
            throw new ArgumentNullException(paramName: nameof(value), message: "cannot set name to null");
    }
    public string LastName
    {
        get => _lastName;
        set =>
            _lastName = value ??
            throw new ArgumentNullException(paramName: nameof(value), message: "cannot set name to null");
    }
    public string HypenatedForPartner(Person partner)
    {
        // _ is a discard variable so we can do the null checking
        // without using "if" statement
        _ = partner ?? throw new ArgumentNullException(paramName: nameof(partner), message: "Partner should not be null");

        return $"{partner.LastName} - {this.LastName}";
    }
}

6. Using Tuples in Switch Pattern Matching

Similar to what I have covered before, but now Bill have shown me that we can use Tuples in pattern-matching switch statement.

Take a look at PeakTimePremium method. Read and understand the business requirements in the comment above it. And now imagine how would you implement it using if-else statements. Then now compares it with the how it is actually implemented using pattern-matching switch statement. The pattern-matching switch statement is very much clearer and easier to understand!

public static class TollCalculations
{
    private static bool IsWeekDay(DateTime timeOfToll) =>
        timeOfToll.DayOfWeek switch
        {
            DayOfWeek.Saturday => false,
            DayOfWeek.Sunday => false,
            _ => true
        };

    private enum TimeBand
    {
        MorningRush,
        DayTime,
        EveningRush,
        Overnight
    }

    private static TimeBand GetTimeBand(DateTime timeOfToll)
    {
        int hour = timeOfToll.Hour;
        if (hour < 6)
            return TimeBand.Overnight;
        else if (hour < 10)
            return TimeBand.MorningRush;
        else if (hour < 16)
            return TimeBand.DayTime;
        else if (hour < 20)
            return TimeBand.EveningRush;
        else
            return TimeBand.Overnight;
    }

    // Calculate a peak time multiplier:
    // weekend multiplier is 1.0
    // late night / early morning is a discount, 0.75
    // daytime during any weekday is 1.5
    // morning rush inbound is double (2.0)
    // morning rush outbound is 1.0
    // evening rush inbound is 1.0
    // evening rush outbound is double (2.0)
    public static decimal PeakTimePremium(DateTime timeOfToll, bool inbound) =>
        (IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
        {
            (true, TimeBand.MorningRush, true) => 2.0m,
            (true, TimeBand.EveningRush, false) => 2.0m,                
            (true, TimeBand.DayTime, _) => 1.5m,
            (_, TimeBand.Overnight, _) => 0.75m,
            (_, _, _) => 1.0m
        };
}

After learning all these new features in C#, my only gripe is that it only works in Visual Studio 2019. Visual Studio 2017 is only supporting up to .NET Core 2.1.

That’s all guys. I hope it somehow helps you. Below is the full video of Bill’s talk:



GD Star Rating
a WordPress rating system
[Summary] "Change your habits: Modern techniques for modern C#" by Bill Wagner, 4.0 out of 5 based on 1 rating

Possibly relevant:

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Incoming Search

.net, c#

No Comment

Add Your Comment