Avoiding the `goto` voodoo?












5















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




















  • 3





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

    – Ewan
    3 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
    3 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
    3 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
    3 hours ago











  • Take a look at the ordering of your function-calls betwee the two examples. It's different.

    – Deduplicator
    2 hours ago
















5















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




















  • 3





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

    – Ewan
    3 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
    3 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
    3 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
    3 hours ago











  • Take a look at the ordering of your function-calls betwee the two examples. It's different.

    – Deduplicator
    2 hours ago














5












5








5


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 6 mins ago







PerpetualJ

















asked 3 hours ago









PerpetualJPerpetualJ

1516




1516








  • 3





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

    – Ewan
    3 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
    3 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
    3 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
    3 hours ago











  • Take a look at the ordering of your function-calls betwee the two examples. It's different.

    – Deduplicator
    2 hours ago














  • 3





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

    – Ewan
    3 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
    3 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
    3 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
    3 hours ago











  • Take a look at the ordering of your function-calls betwee the two examples. It's different.

    – Deduplicator
    2 hours ago








3




3





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

– Ewan
3 hours ago





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

– Ewan
3 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
3 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
3 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
3 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
3 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
3 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
3 hours ago













Take a look at the ordering of your function-calls betwee the two examples. It's different.

– Deduplicator
2 hours ago





Take a look at the ordering of your function-calls betwee the two examples. It's different.

– Deduplicator
2 hours ago










3 Answers
3






active

oldest

votes


















9














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
    3 hours ago






  • 2





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

    – user1118321
    3 hours ago






  • 2





    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
    2 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    1 hour ago











  • @Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

    – user949300
    1 hour ago



















4














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
    2 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
    2 hours ago











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

    – user949300
    1 hour 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
    18 mins 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









9














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
    3 hours ago






  • 2





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

    – user1118321
    3 hours ago






  • 2





    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
    2 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    1 hour ago











  • @Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

    – user949300
    1 hour ago
















9














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
    3 hours ago






  • 2





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

    – user1118321
    3 hours ago






  • 2





    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
    2 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    1 hour ago











  • @Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

    – user949300
    1 hour ago














9












9








9







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 6 mins ago









Andy

1,073819




1,073819










answered 3 hours ago









user1118321user1118321

3,699718




3,699718













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

    – user949300
    3 hours ago






  • 2





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

    – user1118321
    3 hours ago






  • 2





    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
    2 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    1 hour ago











  • @Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

    – user949300
    1 hour ago



















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

    – user949300
    3 hours ago






  • 2





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

    – user1118321
    3 hours ago






  • 2





    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
    2 hours ago






  • 1





    You may use Enum.HasFlag

    – IMil
    1 hour ago











  • @Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

    – user949300
    1 hour ago

















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

– user949300
3 hours ago





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

– user949300
3 hours ago




2




2





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

– user1118321
3 hours ago





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

– user1118321
3 hours ago




2




2





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
2 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
2 hours ago




1




1





You may use Enum.HasFlag

– IMil
1 hour ago





You may use Enum.HasFlag

– IMil
1 hour ago













@Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

– user949300
1 hour ago





@Deduplicator, since the exact bits don't matter, I'd suggest One = 1 << 1, Two = 1 << 2, Three = 1 << 3 for a little more clarity. Though who knows, maybe using 1-based math will confuse the programmer? :-)

– user949300
1 hour ago













4














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
    2 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
    2 hours ago











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

    – user949300
    1 hour ago


















4














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
    2 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
    2 hours ago











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

    – user949300
    1 hour ago
















4












4








4







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 2 hours ago

























answered 3 hours ago









user949300user949300

5,49411426




5,49411426








  • 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
    2 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
    2 hours ago











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

    – user949300
    1 hour 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
    2 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
    2 hours ago











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

    – user949300
    1 hour 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
2 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
2 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
2 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
2 hours ago













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

– user949300
1 hour ago







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

– user949300
1 hour 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
    18 mins 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
    18 mins 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 26 mins ago

























answered 32 mins ago









alephzeroalephzero

27725




27725













  • 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
    18 mins 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
    18 mins 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
18 mins 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
18 mins 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

How to label and detect the document text images

Vallis Paradisi

Tabula Rosettana