Avoiding the `goto` voodoo?
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
|
show 1 more comment
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
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 wheregoto
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 sinceC#
doesn't allow fall-through in theswitch
structure likeC
,C++
, andJava
. 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
|
show 1 more comment
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
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
c# switch-statement goto
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 wheregoto
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 sinceC#
doesn't allow fall-through in theswitch
structure likeC
,C++
, andJava
. 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
|
show 1 more comment
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 wheregoto
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 sinceC#
doesn't allow fall-through in theswitch
structure likeC
,C++
, andJava
. 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
|
show 1 more comment
3 Answers
3
active
oldest
votes
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.
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 suggestOne = 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
|
show 2 more comments
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...
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
add a comment |
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.
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 thegoto
statement and not the concept of single responsibility. I have refactored the code to handle everything with four simpleif
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 suggestOne = 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
|
show 2 more comments
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.
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 suggestOne = 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
|
show 2 more comments
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.
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.
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 suggestOne = 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
|
show 2 more comments
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 suggestOne = 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
|
show 2 more comments
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...
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
add a comment |
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...
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
add a comment |
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...
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...
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
add a comment |
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
add a comment |
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.
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 thegoto
statement and not the concept of single responsibility. I have refactored the code to handle everything with four simpleif
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
add a comment |
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.
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 thegoto
statement and not the concept of single responsibility. I have refactored the code to handle everything with four simpleif
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
add a comment |
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.
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.
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 thegoto
statement and not the concept of single responsibility. I have refactored the code to handle everything with four simpleif
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
add a comment |
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 thegoto
statement and not the concept of single responsibility. I have refactored the code to handle everything with four simpleif
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 theswitch
structure likeC
,C++
, andJava
. 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