简体   繁体   中英

Is it possible to give out a warning when switch (enum) does not cover every enum value AT COMPILE C#

So I have

public enum Type
{
    Cat,
    Dog,
    Horse,
}

private void SomeFunc(Type type)
{
    switch (type)
    {
        case Type.Cat:
            // ...
            break;
        case Type.Dog:
            // ...
            break;

        default:
            throw new System.Exception();
    }
}

Say that at first we only have Cat and Dog. And we already wrote millions of funcs like SomeFunc that uses switch (type).

Now we introduced Horse so I'm going to apply Horse to every switch.

But people in other working branches do not aware of this adding. And when their branches merged into master, there will be some func does not contain Horse in switches.

Well if we unit-test with every Type later we can get Exceptions but we cannot afford to that.

If we can check if all cases are explicitly listed in every switch (enum) that would be perfect. Any ideas? Is it even possible (without wrapping)?

No, it's not possible - at least not out of the box. Switch statements in C# do not have to be exhaustive, and there's no way to require them to be exhaustive.

(Switch expressions in C# 8 will give a warning if they're not exhaustive, but that probably doesn't help you right now.)

You could write a Roslyn analyzer for this though. If you've written Roslyn analyzers before I'd expect it to be reasonably trivial. If you haven't written a Roslyn analyzer before, it can take quite a while to get going, although it's interesting work.

Alternatively, use a 3rd party Roslyn analyzer. I've just found one that seems to work, but I haven't played with it in any depth. Here's an example:

Project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Roslyn.Analyzers" Version="1.0.3.4" PrivateAssets="All" />
  </ItemGroup>

</Project>

Code:

using System;

enum Color
{
    Red, Green, Blue
}

sealed class Program
{
    static void Main(string[] args)
    {
        Color c = Color.Red;

        switch (c)
        {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
//            case Color.Blue:
//                Console.WriteLine("Blue");
//                break;
            default:
                Console.WriteLine("Undefined color");
                break;
        }
    }
}

Result:

Program.cs(14,9): warning ENUM0001: Add missing switch cases. A switch is considered incomplete if it is missing a possible value of the enum or the default case.

I can't vouch for the quality, and you'll probably want to configure which of the analyzers in that package are enabled, but it proves that it's possible. There may well be other analyzers out there that do the same thing - this was just the first search result I found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM