Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
157 views
in Technique[技术] by (71.8m points)

c# - Switch statement without default when dealing with enumerations

This has been a pet peeve of mine since I started using .NET but I was curious in case I was missing something. My code snippet won't compile (please forgive the forced nature of the sample) because (according to the compiler) a return statement is missing:

public enum Decision { Yes, No}

    public class Test
    {
        public string GetDecision(Decision decision)
        {
            switch (decision)
            {
                case Decision.Yes:
                    return "Yes, that's my decision";
                case Decision.No:
                    return "No, that's my decision";

            }
        }
    }

Now I know I can simply place a default statement to get rid of the complier warning, but to my mind not only is that redundant code, its dangerous code. If the enumeration was in another file and another developer comes along and adds Maybe to my enumeration it would be handled by my default clause which knows nothing about Maybes and there's a really good chance we're introducing a logic error.

Whereas, if the compiler let me use my code above, it could then identify that we have a problem as my case statement would no longer cover all the values from my enumeration. Sure sounds a lot safer to me.

This is just so fundamentally wrong to me that I want to know if its just something I'm missing, or do we just have to be very careful when we use enumerations in switch statements?

EDIT: I know I can raise exceptions in the default or add a return outside of the switch, but this are still fundamentally hacks to get round a compiler error that shouldn't be an error.

With regards an enum really just being an int, that's one of .NET's dirty little secrets which is quite embarassing really. Let me declare an enumeration with a finite number of possibilities please and give me a compilation for:

Decision fred = (Decision)123;

and then throw an exception if somebody tries something like:

int foo = 123;
Decision fred = (Decision)foo;

EDIT 2:

A few people have made comments about what happens when the enum is in a different assembly and how this would result in problems. My point is that this is the behaviour I think should happen. If I change a method signature this will lead to issues, my premis is that changing an enumeration should be this same. I get the impression that a lot of people don't think I understand about enums in .NET. I do I just think that the behaviour is wrong, and I'd hoped that someone might have known about some very obscure feature that would have altered my opinion about .NET enums.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Heck, the situation is far worse than just dealing with enums. We don't even do this for bools!

public class Test {        
  public string GetDecision(bool decision) {
    switch (decision) {
       case true: return "Yes, that's my decision";                
       case false: return "No, that's my decision"; 
    }
  }
}

Produces the same error.

Even if you solved all the problems with enums being able to take on any value, you'd still have this issue. The flow analysis rules of the language simply do not consider switches without defaults to be "exhaustive" of all possible code paths, even when you and I know they are.

I would like very much to fix that, but frankly, we have many higher priorities than fixing this silly little issue, so we've never gotten around to it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...