Avoiding the `goto` voodoo?












4















I have a switch structure that has several cases to handle. The switch operates over an enum which presents duplicate code issues:



public enum ExampleEnum {
One,
OneAndTwo,
OneAndThree,
Two,
TwoAndThree,
Three
}


When I enter the switch structure, the functionality for One, Two, and Three are the same even when coupled together. For example:



int i = 0;
if (One || OneAndTwo || OneAndThree)
i++;
if (Two || OneAndTwo || TwoAndThree)
i += 2;
if (Three || OneAndThree || TwoAndThree)
i += 3;


Pretty great and simple stuff right? Well the switch structure can get kind of ugly (so can the if structure) in this scenario so I figured that this may be an acceptable use of the goto statement:



switch (exampleValue) {
case OneAndTwo: i += 2 goto default;
case OneAndThree: i += 3 goto default;
case Two: i += 2 break;
case TwoAndThree: i += 2 goto case Three;
case Three: i += 3 break;
default: i++ break;
}


I see no issue with the code above since it is sequential in nature and isn't misleading as to what could occur; however, this is just my opinion and I know there is a big debate over the use of goto within a professional environment. I currently have this refactored out into an if statement which definitely does what it should, but I hate the duplication factor of it. Why duplicate code when I can just tell it to execute both chunks. Even in my example above there is code duplication and I'd love to remove that too, but that would require more thought.





Important Notes





  • I have edited the post to remove the need for comments related to:




    • Execution path.

    • Calling methods.



  • The switch structure example above is not actually implemented in my code.


  • I am looking for alternatives to handling cases of fall-through.

  • The execution order for each case is irrelevant in this particular code.




In this particular case the switch structure has cases which should fall-through to other cases which is not supported in C# like it is with C, C++, and Java. Would this be an acceptable use in a professional environment or should I leave it as my if structure?



Is there a more concise way of accomplishing this without effecting readability and maintainability?










share|improve this question




















  • 5





    there is no big debate. no one uses goto. make your enum a flag

    – Ewan
    6 hours ago






  • 2





    @Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

    – PerpetualJ
    5 hours ago






  • 1





    it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

    – Ewan
    5 hours ago











  • @Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

    – PerpetualJ
    5 hours ago






  • 1





    @Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

    – John Douma
    2 hours ago
















4















I have a switch structure that has several cases to handle. The switch operates over an enum which presents duplicate code issues:



public enum ExampleEnum {
One,
OneAndTwo,
OneAndThree,
Two,
TwoAndThree,
Three
}


When I enter the switch structure, the functionality for One, Two, and Three are the same even when coupled together. For example:



int i = 0;
if (One || OneAndTwo || OneAndThree)
i++;
if (Two || OneAndTwo || TwoAndThree)
i += 2;
if (Three || OneAndThree || TwoAndThree)
i += 3;


Pretty great and simple stuff right? Well the switch structure can get kind of ugly (so can the if structure) in this scenario so I figured that this may be an acceptable use of the goto statement:



switch (exampleValue) {
case OneAndTwo: i += 2 goto default;
case OneAndThree: i += 3 goto default;
case Two: i += 2 break;
case TwoAndThree: i += 2 goto case Three;
case Three: i += 3 break;
default: i++ break;
}


I see no issue with the code above since it is sequential in nature and isn't misleading as to what could occur; however, this is just my opinion and I know there is a big debate over the use of goto within a professional environment. I currently have this refactored out into an if statement which definitely does what it should, but I hate the duplication factor of it. Why duplicate code when I can just tell it to execute both chunks. Even in my example above there is code duplication and I'd love to remove that too, but that would require more thought.





Important Notes





  • I have edited the post to remove the need for comments related to:




    • Execution path.

    • Calling methods.



  • The switch structure example above is not actually implemented in my code.


  • I am looking for alternatives to handling cases of fall-through.

  • The execution order for each case is irrelevant in this particular code.




In this particular case the switch structure has cases which should fall-through to other cases which is not supported in C# like it is with C, C++, and Java. Would this be an acceptable use in a professional environment or should I leave it as my if structure?



Is there a more concise way of accomplishing this without effecting readability and maintainability?










share|improve this question




















  • 5





    there is no big debate. no one uses goto. make your enum a flag

    – Ewan
    6 hours ago






  • 2





    @Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

    – PerpetualJ
    5 hours ago






  • 1





    it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

    – Ewan
    5 hours ago











  • @Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

    – PerpetualJ
    5 hours ago






  • 1





    @Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

    – John Douma
    2 hours ago














4












4








4


1






I have a switch structure that has several cases to handle. The switch operates over an enum which presents duplicate code issues:



public enum ExampleEnum {
One,
OneAndTwo,
OneAndThree,
Two,
TwoAndThree,
Three
}


When I enter the switch structure, the functionality for One, Two, and Three are the same even when coupled together. For example:



int i = 0;
if (One || OneAndTwo || OneAndThree)
i++;
if (Two || OneAndTwo || TwoAndThree)
i += 2;
if (Three || OneAndThree || TwoAndThree)
i += 3;


Pretty great and simple stuff right? Well the switch structure can get kind of ugly (so can the if structure) in this scenario so I figured that this may be an acceptable use of the goto statement:



switch (exampleValue) {
case OneAndTwo: i += 2 goto default;
case OneAndThree: i += 3 goto default;
case Two: i += 2 break;
case TwoAndThree: i += 2 goto case Three;
case Three: i += 3 break;
default: i++ break;
}


I see no issue with the code above since it is sequential in nature and isn't misleading as to what could occur; however, this is just my opinion and I know there is a big debate over the use of goto within a professional environment. I currently have this refactored out into an if statement which definitely does what it should, but I hate the duplication factor of it. Why duplicate code when I can just tell it to execute both chunks. Even in my example above there is code duplication and I'd love to remove that too, but that would require more thought.





Important Notes





  • I have edited the post to remove the need for comments related to:




    • Execution path.

    • Calling methods.



  • The switch structure example above is not actually implemented in my code.


  • I am looking for alternatives to handling cases of fall-through.

  • The execution order for each case is irrelevant in this particular code.




In this particular case the switch structure has cases which should fall-through to other cases which is not supported in C# like it is with C, C++, and Java. Would this be an acceptable use in a professional environment or should I leave it as my if structure?



Is there a more concise way of accomplishing this without effecting readability and maintainability?










share|improve this question
















I have a switch structure that has several cases to handle. The switch operates over an enum which presents duplicate code issues:



public enum ExampleEnum {
One,
OneAndTwo,
OneAndThree,
Two,
TwoAndThree,
Three
}


When I enter the switch structure, the functionality for One, Two, and Three are the same even when coupled together. For example:



int i = 0;
if (One || OneAndTwo || OneAndThree)
i++;
if (Two || OneAndTwo || TwoAndThree)
i += 2;
if (Three || OneAndThree || TwoAndThree)
i += 3;


Pretty great and simple stuff right? Well the switch structure can get kind of ugly (so can the if structure) in this scenario so I figured that this may be an acceptable use of the goto statement:



switch (exampleValue) {
case OneAndTwo: i += 2 goto default;
case OneAndThree: i += 3 goto default;
case Two: i += 2 break;
case TwoAndThree: i += 2 goto case Three;
case Three: i += 3 break;
default: i++ break;
}


I see no issue with the code above since it is sequential in nature and isn't misleading as to what could occur; however, this is just my opinion and I know there is a big debate over the use of goto within a professional environment. I currently have this refactored out into an if statement which definitely does what it should, but I hate the duplication factor of it. Why duplicate code when I can just tell it to execute both chunks. Even in my example above there is code duplication and I'd love to remove that too, but that would require more thought.





Important Notes





  • I have edited the post to remove the need for comments related to:




    • Execution path.

    • Calling methods.



  • The switch structure example above is not actually implemented in my code.


  • I am looking for alternatives to handling cases of fall-through.

  • The execution order for each case is irrelevant in this particular code.




In this particular case the switch structure has cases which should fall-through to other cases which is not supported in C# like it is with C, C++, and Java. Would this be an acceptable use in a professional environment or should I leave it as my if structure?



Is there a more concise way of accomplishing this without effecting readability and maintainability?







c# switch-statement goto






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 hours ago







PerpetualJ

















asked 6 hours ago









PerpetualJPerpetualJ

1517




1517








  • 5





    there is no big debate. no one uses goto. make your enum a flag

    – Ewan
    6 hours ago






  • 2





    @Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

    – PerpetualJ
    5 hours ago






  • 1





    it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

    – Ewan
    5 hours ago











  • @Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

    – PerpetualJ
    5 hours ago






  • 1





    @Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

    – John Douma
    2 hours ago














  • 5





    there is no big debate. no one uses goto. make your enum a flag

    – Ewan
    6 hours ago






  • 2





    @Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

    – PerpetualJ
    5 hours ago






  • 1





    it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

    – Ewan
    5 hours ago











  • @Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

    – PerpetualJ
    5 hours ago






  • 1





    @Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

    – John Douma
    2 hours ago








5




5





there is no big debate. no one uses goto. make your enum a flag

– Ewan
6 hours ago





there is no big debate. no one uses goto. make your enum a flag

– Ewan
6 hours ago




2




2





@Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

– PerpetualJ
5 hours ago





@Ewan Hence there is a big debate; there are scenarios where goto should be used, but in modern code it's usually for obfuscation purposes.

– PerpetualJ
5 hours ago




1




1





it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

– Ewan
5 hours ago





it sounds like you want to have a big debate. But you'll need a better example of a good case to use goto. flag enum neatly solves this one, even if your if statement example wasnt acceptable and it looks fine to me

– Ewan
5 hours ago













@Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

– PerpetualJ
5 hours ago





@Ewan I'm here to avoid using it and am looking for alternatives (a fantastic one has already been offered), but to since you stated I'd need a better example; the current post is a good example since C# doesn't allow fall-through in the switch structure like C, C++, and Java. This is per the documentation over on MSDN; however, I believe we are getting off topic at this point.

– PerpetualJ
5 hours ago




1




1





@Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

– John Douma
2 hours ago





@Ewan No one uses the goto. When is the last time you looked at the Linux kernel source code?

– John Douma
2 hours ago










3 Answers
3






active

oldest

votes


















12














I find the code hard to read with the goto statements. I would recommend structuring your enum differently. For example, if your enum was a bitfield where each bit represented one of the choices, it could look like this:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100
};


The Flags attribute tells the compiler that you're setting up values which don't overlap. The code that calls this code could set the appropriate bit. You could then do something like this to make it clear what's happening:



if (myEnum.HasFlag(ExampleEnum.One))
{
CallOne();
}
if (myEnum.HasFlag(ExampleEnum.Two))
{
CallTwo();
}
if (myEnum.HasFlag(ExampleEnum.Three))
{
CallThree();
}


This requires the code that sets up myEnum to set the bitfields properly and marked with the Flags attribute. But you can do that by changing the values of the enums in your example to:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100,
OneAndTwo = One | Two,
OneAndThree = One | Three,
TwoAndThree = Two | Three
};


When you write a number in the form 0bxxxx, you're specifying it in binary. So you can see that we set bit 1, 2, or 3 (well, technically 0, 1, or 2, but you get the idea). You can also name combinations by using a bitwise OR if the combinations might be frequently set together.






share|improve this answer


























  • Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

    – user949300
    5 hours ago






  • 2





    It appears so! But it must be C# 7.0 or later, I guess.

    – user1118321
    5 hours ago






  • 4





    Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

    – Deduplicator
    5 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    4 hours ago






  • 2





    The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

    – Joe Sewell
    2 hours ago





















7














The best answer is use polymorphism.



Another answer, which, IMO, makes the if stuff clearer and arguably shorter:



if (One || OneAndTwo)
CallOne();
if (OneAndTwo || Two)
CallTwo();
if (OneAndThree || TwoAndThree || Three)
CallThree();


goto is probably my 58th choice here...






share|improve this answer





















  • 1





    +1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

    – Erik Eidt
    5 hours ago






  • 1





    Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

    – Deduplicator
    4 hours ago











  • Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

    – user949300
    4 hours ago





















0














IMO the root of the problem is that this piece of code shouldn't even exist.



You apparently have three independent conditions, and three independent actions to take if those conditions are true. So why is all that being funnelled into one piece of code that needs three Boolean flags to tell it what to do (whether or not you obfuscate them into an enum) and then does some combination of three independent things? The single responsibility principle seems to be having an off-day here.



Put the calls to the three functions where the belong (i.e. where you discover the need to do the actions) and consign the code in these examples to the recycle bin.



If there were ten flags and actions not three, would you extend this sort of code to handle 1024 different combinations? I hope not! If 1024 is too many, 8 is also too many, for the same reason.






share|improve this answer


























  • So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

    – PerpetualJ
    2 hours ago






  • 1





    As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

    – Deduplicator
    2 hours ago













Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "131"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385901%2favoiding-the-goto-voodoo%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









12














I find the code hard to read with the goto statements. I would recommend structuring your enum differently. For example, if your enum was a bitfield where each bit represented one of the choices, it could look like this:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100
};


The Flags attribute tells the compiler that you're setting up values which don't overlap. The code that calls this code could set the appropriate bit. You could then do something like this to make it clear what's happening:



if (myEnum.HasFlag(ExampleEnum.One))
{
CallOne();
}
if (myEnum.HasFlag(ExampleEnum.Two))
{
CallTwo();
}
if (myEnum.HasFlag(ExampleEnum.Three))
{
CallThree();
}


This requires the code that sets up myEnum to set the bitfields properly and marked with the Flags attribute. But you can do that by changing the values of the enums in your example to:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100,
OneAndTwo = One | Two,
OneAndThree = One | Three,
TwoAndThree = Two | Three
};


When you write a number in the form 0bxxxx, you're specifying it in binary. So you can see that we set bit 1, 2, or 3 (well, technically 0, 1, or 2, but you get the idea). You can also name combinations by using a bitwise OR if the combinations might be frequently set together.






share|improve this answer


























  • Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

    – user949300
    5 hours ago






  • 2





    It appears so! But it must be C# 7.0 or later, I guess.

    – user1118321
    5 hours ago






  • 4





    Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

    – Deduplicator
    5 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    4 hours ago






  • 2





    The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

    – Joe Sewell
    2 hours ago


















12














I find the code hard to read with the goto statements. I would recommend structuring your enum differently. For example, if your enum was a bitfield where each bit represented one of the choices, it could look like this:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100
};


The Flags attribute tells the compiler that you're setting up values which don't overlap. The code that calls this code could set the appropriate bit. You could then do something like this to make it clear what's happening:



if (myEnum.HasFlag(ExampleEnum.One))
{
CallOne();
}
if (myEnum.HasFlag(ExampleEnum.Two))
{
CallTwo();
}
if (myEnum.HasFlag(ExampleEnum.Three))
{
CallThree();
}


This requires the code that sets up myEnum to set the bitfields properly and marked with the Flags attribute. But you can do that by changing the values of the enums in your example to:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100,
OneAndTwo = One | Two,
OneAndThree = One | Three,
TwoAndThree = Two | Three
};


When you write a number in the form 0bxxxx, you're specifying it in binary. So you can see that we set bit 1, 2, or 3 (well, technically 0, 1, or 2, but you get the idea). You can also name combinations by using a bitwise OR if the combinations might be frequently set together.






share|improve this answer


























  • Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

    – user949300
    5 hours ago






  • 2





    It appears so! But it must be C# 7.0 or later, I guess.

    – user1118321
    5 hours ago






  • 4





    Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

    – Deduplicator
    5 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    4 hours ago






  • 2





    The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

    – Joe Sewell
    2 hours ago
















12












12








12







I find the code hard to read with the goto statements. I would recommend structuring your enum differently. For example, if your enum was a bitfield where each bit represented one of the choices, it could look like this:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100
};


The Flags attribute tells the compiler that you're setting up values which don't overlap. The code that calls this code could set the appropriate bit. You could then do something like this to make it clear what's happening:



if (myEnum.HasFlag(ExampleEnum.One))
{
CallOne();
}
if (myEnum.HasFlag(ExampleEnum.Two))
{
CallTwo();
}
if (myEnum.HasFlag(ExampleEnum.Three))
{
CallThree();
}


This requires the code that sets up myEnum to set the bitfields properly and marked with the Flags attribute. But you can do that by changing the values of the enums in your example to:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100,
OneAndTwo = One | Two,
OneAndThree = One | Three,
TwoAndThree = Two | Three
};


When you write a number in the form 0bxxxx, you're specifying it in binary. So you can see that we set bit 1, 2, or 3 (well, technically 0, 1, or 2, but you get the idea). You can also name combinations by using a bitwise OR if the combinations might be frequently set together.






share|improve this answer















I find the code hard to read with the goto statements. I would recommend structuring your enum differently. For example, if your enum was a bitfield where each bit represented one of the choices, it could look like this:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100
};


The Flags attribute tells the compiler that you're setting up values which don't overlap. The code that calls this code could set the appropriate bit. You could then do something like this to make it clear what's happening:



if (myEnum.HasFlag(ExampleEnum.One))
{
CallOne();
}
if (myEnum.HasFlag(ExampleEnum.Two))
{
CallTwo();
}
if (myEnum.HasFlag(ExampleEnum.Three))
{
CallThree();
}


This requires the code that sets up myEnum to set the bitfields properly and marked with the Flags attribute. But you can do that by changing the values of the enums in your example to:



[Flags]
public enum ExampleEnum {
One = 0b0001,
Two = 0b0010,
Three = 0b0100,
OneAndTwo = One | Two,
OneAndThree = One | Three,
TwoAndThree = Two | Three
};


When you write a number in the form 0bxxxx, you're specifying it in binary. So you can see that we set bit 1, 2, or 3 (well, technically 0, 1, or 2, but you get the idea). You can also name combinations by using a bitwise OR if the combinations might be frequently set together.







share|improve this answer














share|improve this answer



share|improve this answer








edited 2 hours ago









Andy

1,073819




1,073819










answered 5 hours ago









user1118321user1118321

3,729719




3,729719













  • Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

    – user949300
    5 hours ago






  • 2





    It appears so! But it must be C# 7.0 or later, I guess.

    – user1118321
    5 hours ago






  • 4





    Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

    – Deduplicator
    5 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    4 hours ago






  • 2





    The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

    – Joe Sewell
    2 hours ago





















  • Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

    – user949300
    5 hours ago






  • 2





    It appears so! But it must be C# 7.0 or later, I guess.

    – user1118321
    5 hours ago






  • 4





    Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

    – Deduplicator
    5 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    4 hours ago






  • 2





    The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

    – Joe Sewell
    2 hours ago



















Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

– user949300
5 hours ago





Does C# have binary constants? Usually I use hex for flags but this is a case where binary would be superior.

– user949300
5 hours ago




2




2





It appears so! But it must be C# 7.0 or later, I guess.

– user1118321
5 hours ago





It appears so! But it must be C# 7.0 or later, I guess.

– user1118321
5 hours ago




4




4





Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

– Deduplicator
5 hours ago





Anyway, one could also do it like this: public enum ExampleEnum { One = 1 << 0, Two = 1 << 1, Three = 1 << 2, OneAndTwo = One | Two, OneAndThree = One | Three, TwoAndThree = Two | Three };. No need to insist on C#7+.

– Deduplicator
5 hours ago




1




1





You may use Enum.HasFlag

– IMil
4 hours ago





You may use Enum.HasFlag

– IMil
4 hours ago




2




2





The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

– Joe Sewell
2 hours ago







The [Flags] attribute doesn't signal anything to the compiler. This is why you still have to explicitly declare the enum values as powers of 2.

– Joe Sewell
2 hours ago















7














The best answer is use polymorphism.



Another answer, which, IMO, makes the if stuff clearer and arguably shorter:



if (One || OneAndTwo)
CallOne();
if (OneAndTwo || Two)
CallTwo();
if (OneAndThree || TwoAndThree || Three)
CallThree();


goto is probably my 58th choice here...






share|improve this answer





















  • 1





    +1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

    – Erik Eidt
    5 hours ago






  • 1





    Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

    – Deduplicator
    4 hours ago











  • Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

    – user949300
    4 hours ago


















7














The best answer is use polymorphism.



Another answer, which, IMO, makes the if stuff clearer and arguably shorter:



if (One || OneAndTwo)
CallOne();
if (OneAndTwo || Two)
CallTwo();
if (OneAndThree || TwoAndThree || Three)
CallThree();


goto is probably my 58th choice here...






share|improve this answer





















  • 1





    +1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

    – Erik Eidt
    5 hours ago






  • 1





    Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

    – Deduplicator
    4 hours ago











  • Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

    – user949300
    4 hours ago
















7












7








7







The best answer is use polymorphism.



Another answer, which, IMO, makes the if stuff clearer and arguably shorter:



if (One || OneAndTwo)
CallOne();
if (OneAndTwo || Two)
CallTwo();
if (OneAndThree || TwoAndThree || Three)
CallThree();


goto is probably my 58th choice here...






share|improve this answer















The best answer is use polymorphism.



Another answer, which, IMO, makes the if stuff clearer and arguably shorter:



if (One || OneAndTwo)
CallOne();
if (OneAndTwo || Two)
CallTwo();
if (OneAndThree || TwoAndThree || Three)
CallThree();


goto is probably my 58th choice here...







share|improve this answer














share|improve this answer



share|improve this answer








edited 5 hours ago

























answered 5 hours ago









user949300user949300

5,52411426




5,52411426








  • 1





    +1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

    – Erik Eidt
    5 hours ago






  • 1





    Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

    – Deduplicator
    4 hours ago











  • Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

    – user949300
    4 hours ago
















  • 1





    +1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

    – Erik Eidt
    5 hours ago






  • 1





    Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

    – Deduplicator
    4 hours ago











  • Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

    – user949300
    4 hours ago










1




1





+1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

– Erik Eidt
5 hours ago





+1 for suggesting polymorphism, though ideally that might simplify the client code down to just "Call();", using tell don't ask -- to push the decision logic away from the consuming client and into the class mechanism and hierarchy.

– Erik Eidt
5 hours ago




1




1





Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

– Deduplicator
4 hours ago





Proclaiming anything the best sight unseen is certainly very brave. But without additional info, I suggest a bit of scepticism and keeping an open mind. Perhaps it suffers from combinatorial explosion?

– Deduplicator
4 hours ago













Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

– user949300
4 hours ago







Wow, I think this is the first time I've ever been downvoted for suggesting polymorphism. :-)

– user949300
4 hours ago













0














IMO the root of the problem is that this piece of code shouldn't even exist.



You apparently have three independent conditions, and three independent actions to take if those conditions are true. So why is all that being funnelled into one piece of code that needs three Boolean flags to tell it what to do (whether or not you obfuscate them into an enum) and then does some combination of three independent things? The single responsibility principle seems to be having an off-day here.



Put the calls to the three functions where the belong (i.e. where you discover the need to do the actions) and consign the code in these examples to the recycle bin.



If there were ten flags and actions not three, would you extend this sort of code to handle 1024 different combinations? I hope not! If 1024 is too many, 8 is also too many, for the same reason.






share|improve this answer


























  • So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

    – PerpetualJ
    2 hours ago






  • 1





    As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

    – Deduplicator
    2 hours ago


















0














IMO the root of the problem is that this piece of code shouldn't even exist.



You apparently have three independent conditions, and three independent actions to take if those conditions are true. So why is all that being funnelled into one piece of code that needs three Boolean flags to tell it what to do (whether or not you obfuscate them into an enum) and then does some combination of three independent things? The single responsibility principle seems to be having an off-day here.



Put the calls to the three functions where the belong (i.e. where you discover the need to do the actions) and consign the code in these examples to the recycle bin.



If there were ten flags and actions not three, would you extend this sort of code to handle 1024 different combinations? I hope not! If 1024 is too many, 8 is also too many, for the same reason.






share|improve this answer


























  • So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

    – PerpetualJ
    2 hours ago






  • 1





    As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

    – Deduplicator
    2 hours ago
















0












0








0







IMO the root of the problem is that this piece of code shouldn't even exist.



You apparently have three independent conditions, and three independent actions to take if those conditions are true. So why is all that being funnelled into one piece of code that needs three Boolean flags to tell it what to do (whether or not you obfuscate them into an enum) and then does some combination of three independent things? The single responsibility principle seems to be having an off-day here.



Put the calls to the three functions where the belong (i.e. where you discover the need to do the actions) and consign the code in these examples to the recycle bin.



If there were ten flags and actions not three, would you extend this sort of code to handle 1024 different combinations? I hope not! If 1024 is too many, 8 is also too many, for the same reason.






share|improve this answer















IMO the root of the problem is that this piece of code shouldn't even exist.



You apparently have three independent conditions, and three independent actions to take if those conditions are true. So why is all that being funnelled into one piece of code that needs three Boolean flags to tell it what to do (whether or not you obfuscate them into an enum) and then does some combination of three independent things? The single responsibility principle seems to be having an off-day here.



Put the calls to the three functions where the belong (i.e. where you discover the need to do the actions) and consign the code in these examples to the recycle bin.



If there were ten flags and actions not three, would you extend this sort of code to handle 1024 different combinations? I hope not! If 1024 is too many, 8 is also too many, for the same reason.







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 3 hours ago









alephzeroalephzero

28525




28525













  • So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

    – PerpetualJ
    2 hours ago






  • 1





    As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

    – Deduplicator
    2 hours ago





















  • So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

    – PerpetualJ
    2 hours ago






  • 1





    As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

    – Deduplicator
    2 hours ago



















So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

– PerpetualJ
2 hours ago





So grateful for this answer! In my opinion the code is perfectly valid and genericized for this particular post. The question is in relation to the goto statement and not the concept of single responsibility. I have refactored the code to handle everything with four simple if statements. More to the point on your answer, there is nothing wrong with multiple if statements in the same method so long as they achieve a related goal to the method and simply alter the execution path. In my actual code each piece isn't actually a method call, but a single line execution.

– PerpetualJ
2 hours ago




1




1





As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

– Deduplicator
2 hours ago







As a point of fact, there are many well-designed APIs which have all kinds of flags, options, and assorted other parameters. Some may be passed on, some have direct effects, and yet others potentially be ignored, without breaking SRP. Anyway, the function could even be decoding some external input, who knows? Also, reductio ad absurdum often leads to absurd results, especially if the starting-point isn't even all that solid.

– Deduplicator
2 hours ago




















draft saved

draft discarded




















































Thanks for contributing an answer to Software Engineering Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f385901%2favoiding-the-goto-voodoo%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

GameSpot

connect to host localhost port 22: Connection refused

Getting a Wifi WPA2 wifi connection