Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid Switch syntax builds successfully?

Could someone please help enlighten me?

I went to check-in some changes to TFS and my check-in was rejected. It prompted me to take a look at a switch statement I had edited.

What I've found is that Visual Studio 2017 claims there is no compile time issue and allows me to build and deploy the application successfully. On top of that, even the unit test for the method appears to be passing as intended.

public enum PaymentStatus
{
    Issued,
    Cleared,
    Voided,
    Paid,
    Requested,
    Stopped,
    Unknown
}

public class PaymentViewModel
{
    public PaymentStatus Status { get; set; }

    ...

    public String StatusString
    {
        get
        {
            switch (this.Status)
            {
                case PaymentStatus.Cleared:
                    return "Cleared";
                case PaymentStatus.Issued:
                    return "Issued";
                case PaymentStatus.Voided:
                    return "Voided";
                case PaymentStatus.Paid:
                    return "Paid";
                case PaymentStatus.Requested:
                    return "Requested";
                case PaymentStatus.Stopped:
                    return "Stopped";
                case PaymentStatus Unknown:
                    return "Unknown";
                default:
                    throw new InavlidEnumerationException(this.Status);
            }
        }
    }
}

So, please note that the line "case PaymentStatus Unknown" is missing the '.' dot operator. As mentioned, the project builds and runs; but failed to check-in with the gated build server.

Also, note that the following test is passing:

[TestMethod]
public void StatusStringTest_Unknown()
{
    var model = new PaymentViewModel()
    {
        Status = PaymentStatus.Unknown
    }

    Assert.AreEqual("Unknown", model.StatusString);
}

Here are some images showing no squigglies and it does indeed build fine: Switch-No-Compiler-Error

And, the passing test method: Switch-Passing-Test

Lastly, note that I ran the test with just a static string rather than using the resource file and it passes. I just left out the resource file stuff for simplicity's sake in the code above.

Any thoughts on this are most appreciated! Thanks in Advance!

like image 873
Urk Avatar asked Oct 05 '17 19:10

Urk


1 Answers

This compiles because your Visual Studio interprets PaymentStatus Unknown as a pattern matching, which is a new feature of C# 7:

  • PaymentStatus is the type,
  • Unknown is the name,
  • No condition (i.e. pattern always matches).

The intended use case for this syntax was something like this:

switch (this.Status) {
    case PaymentStatus ended when ended==PaymentStatus.Stopped || ended==PaymentStatus.Voided:
        return "No payment for you!";
    default:
        return "You got lucky this time!";
}

If TFS is set up to use an older version of C#, it is going to reject this source.

Note: The reason your unit test works is that the remaining cases are all done correctly. A test case for throwing InavlidEnumerationException(this.Status) would fail, though, because the switch would interpret any unknown value as, well, PaymentStatus.Unknown.

like image 163
Sergey Kalinichenko Avatar answered Oct 04 '22 14:10

Sergey Kalinichenko