### SODEVE

browse by category or date

# [Summary] “Change your habits: Modern techniques for modern C#” by Bill Wagner

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
}
}
```

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

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)
}

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