browse by category or date

Today I was testing my JSON Table Editor on Microsoft Edge browser. After a while, I realize it failed to close the child window. After testing the same functionality on other browsers (Mozilla Firefox, Opera, Google Chrome), I can confirm that this problem only occurred in Microsoft Edge (version shown below) and Microsoft Internet Explorer 11 (it still exists lurking under Edge’s shadow :D)

Since this should be a Microsoft Edge bug, I filed a bug report https://aka.ms/AA7nfw2 (Only Windows 10 users will be able to see this bug report). The bug report details is below:

1. visit https://sodeve.page.link/tvQxphqV41i3KAiw9

2. Click the calendar icon in Locations column, a new tab will open

3. On the new tab, click “Finish Editing”, the tab will close

4. Click the calendar icon in Locations column, any other row, new tab will open

5. On the new tab, click “Finish Editing”, tab is failed to close

On other browsers, step 5 always successfully close the tab.

I hope they will take a look into this ASAP!

About Hardono

Hi, 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.

Cannot be stressed enough, the importance of social responsibility:

[Sent by Gov.sg – 11 Mar]

COVID-19: Social responsibility is critical

➡Many locally transmitted cases were caused by individuals attending social activities though sick
– 35 of 160 confirmed cases did not minimise social contact even with symptoms
– 22% went to work
– 24% doctor hopped; 8 visited three or more

Protecting our seniors
– All senior-centric activities by government agencies will be suspended for 14 days (till 24 Mar 2020)
– Care services for seniors will continue, with added precautions
– All who are sick should see a doctor and stay at home

More: go.gov.sg/PAseniors

Two clusters caused by socially irresponsible behaviour: go.gov.sg/clusters

Updates on the number of confirmed and discharged cases:

[Sent by Gov.sg]

COVID-19: 11 Mar Update

As of 12pm:
New cases: 12
Total cases in Singapore: 178
Discharged today: 3
Total discharged: 96
Total remaining in Hospital: 82

Of the new cases, 1 is part of the SAFRA Jurong cluster, 8 are imported cases, 1 is linked to an imported case, and 2 are unlinked.

Most in hospital are stable or improving. 9 are in the intensive care unit – three less than yesterday.

go.gov.sg/moh11mar

Stay safe everyone!

About Hardono

Hi, 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.

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

Hi, 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.