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:



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.

Possibly relevant:

Update on the number of confirmed cases:

[Sent by Gov.sg]

COVID-19: 10 Mar Update

As of 12pm:
New cases: 6
Total cases in Singapore: 166
Discharged today: 0
Total discharged: 93
Total remaining in Hospital: 73

Of the new cases, 3 are part of the SAFRA Jurong cluster, 2 are linked to a previous case, 1 is unlinked.

Most in hospital are stable or improving. 12 are in the intensive care unit.

go.gov.sg/moh10mar

Be socially responsible
– See a doctor and stay home if sick, even with mild flu-like symptoms
– Don’t doctor-hop
– Cooperate during contact tracing

Stay safe everyone!

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.

Possibly relevant:

Update on the number of confirmed and discharged cases:

[Sent by Gov.sg]

COVID-19: 9 Mar Update

As of 12pm:
New cases: 10
Total cases in Singapore: 160
Discharged today: 3
Total discharged: 93
Total remaining in Hospital: 67

Of the new cases, 6 are part of the SAFRA Jurong cluster, 1 is linked to a previous cluster, 3 are imported cases.

Most in hospital are stable or improving. 10 are in the intensive care unit.

go.gov.sg/moh9mar

🛳 Precautionary measures for Costa Fortuna
– Cruise ship Costa Fortuna, based in SG, is scheduled to return on 10 Mar
– All of its passengers had embarked earlier from Singapore, and completed pre-embarkation checks
– No passengers have fever or respiratory illness
– Doctor on board will check passengers and crew to ensure they are healthy before disembarkation
– Temp screening before entering SG, swab tests if exhibiting fever or respiratory illness
– SG cruise terminals remain open to scheduled calls
– Unscheduled calls in SG disallowed since 24 Feb

go.gov.sg/mpa9mar

Thoughts and prayers for those who are infected, especially those who are in the intensive care unit. Stay safe and be vigilant everyone!

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.

Possibly relevant: