I have a few methods that are called from within a few other methods. When in some of the methods a certain action is performed, I would like to go back to the very first method and skip the rest of the code. At the moment, I use booleans to check the "status" of the program but I would like to avoid this because the methods should be void since in essence they don't need to return anything. I found stuff like goto but that only works in the same method.
Question: is there a way to jump to a specific point in the code in a different method in C#? I found stuff on other languages but not a lot on C#.
Current situation:
void test1()
{
bool status = test2();
if (!status)
return; // the other stuff will not get done
Debug.WriteLine("Initialization OK");
}
bool test2()
{
bool status = test3();
if (!status)
return false; // the other stuff will not get done
// do other stuff
return true;
}
bool test3()
{
if (xxx)
return false; // the other stuff will not get done
else
// do other stuff
return true;
}
Wanted situation:
void test1()
{
test2();
// do other stuff
Debug.WriteLine("Initialization OK");
GOTOHERE:
Debug.WriteLine("Initialization NOT OK");
}
void test2()
{
test3();
// do other stuff
}
void test3()
{
if (xxx)
**GOTOHERE**; // Go directly to the location in test1() so that all unnecessary code is skipped
// do other stuff
}
I was surprised to learn that C# does actually support a GOTO command. But it is designed to allow exit from deep nested loops.
This article explains it and gives lots of examples: https://www.dotnetperls.com/goto
However
Unless you are still coding in 1970 then using GOTO is considered very bad practice. It makes code maintenance very difficult. And it even causes problems and performance issues, and makes life for the JIT compiler more difficult.
The go to statement as it stands is just too primitive, it is too much
an invitation to make a mess of one's program.
Edsger W. Dijkstra
Returning something from your method to indicate what you should do afterwards is exactly what you should do. Thus return a boolean indicating if test2 or test3 succeeded and use that value to indicate if you want to proceed further. Don´t use goto nowadays as it only leeds to spaghetti-code, that is hard to maintain. To determine under which circumstances control-flow should jump to GOTOHERE you´d need to scan your entire code for that specific goto-statement.
In your case you want to indicate if some initialization-code works correct. Thus you can also throw an exception:
void test3()
{
if (xxx)
throw new Exception("Some text");
// do other stuff
}
This way you don´t need to return anything from your method, but handle the exception appropriately:
void test1()
{
try { test2(); }
catch {
// some exception-handling such as logging
return;
}
Debug.WriteLine("Initialization OK");
}
This has the advantage that you don´t need to check in test2 if test3 succeeded, allowing you to let the exception bubble through your methods until it is finally handled by a catch. If no catch was found in the entire callstack your app will probably terminate.
C# does have the goto keyword, which works just like in other languages. Declare a label as label_you_want_to_jump_to:, and use goto label_you_want_to_jump_to (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto).
Now that this is said, it is usually a bad idea to use goto, especially in such a way. Your problem might be solved more easily by refactoring a bit. Splitting test3 into two functions, reducing the amount of nesting might be such a way. You may also throw an exception in test3, and catch it in test1. It all depends on what you want to do.
If you get rid of the explicit bools (which are redundant), your (rather contrived) example looks a lot "cleaner" in my opinion:
void test1()
{
if (test2())
{
Debug.WriteLine("Initialization OK");
}
}
bool test2()
{
return test3();
}
bool test3()
{
return xxx;
}
I also prefer to use positive rather than negative conditions, so "if (true)" rather than "if (!false)". This avoids double negatives, which are harder to understand.
Effectively we are using Predicate Logic. We can combine our predicates (methods than return bool without side effects) using the normal logic operators. Consider this example:
bool test4()
{
if (test1())
{
if (test2())
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
We note that this is simply a logical conjunction (and) of test1 and test2, so can simply use the && conjunction operator to make this much clearer:
bool test4()
{
return test1() && test2();
}
Similarly for logical disjunction (or):
bool test5()
{
if (test1())
{
return true;
}
else if (test2())
{
return true;
}
else
{
return false;
}
}
We can write this instead as:
bool test5()
{
return test1() || test2();
}
I don't recommend it, but the simple answer to your question is to use a goto statement.
See: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto
You should, however, really be returning values from previous method calls that you can use to determine if you need to run other code.
You can also throw exceptions, but in general I'm not a fan of using them for control of flow unless the circumstance is exceptional (hence the name, I suppose). If you expect that control may flow this way or that, it is not exceptional.
I do understand your point but breaking the sequence of events (aka jumping) is not good practice. Your code becomes unreadable because the reader needs to jump from one place to another. There is a reason why you can't jump out of the current method:
What follows is a really simplified explanation. I am glosing over many details.
If you have knowledge about how the stack works you'll know that the runtime will push a new stack frame onto the stack for each new method invocation. That new stack frame contains the method's local variables as well as other things that are implementation details. If you want to jump to another method the runtime would need to push a new stack frame onto your stack in order to create those local variables for that method. So your goto would become a method invocation rather than a jump statement. Which is weird and not what you/we want. Use normal method invocations in such scenarios rather than jump statements.
There are widly accepted jumping statements like return, break and continue. goto is not one of them, although I consider goto case to be a valid solution in some cases.
Returning the information about what to do next is the correct behaviour here.
I do agree that returning a bool is not very expressive from a sematic perspective, at least not whith your current method names. Naming improvement suggestion:
void DoTest1();
bool TryTest2();
bool TryTest3();
FYI
bool flag;
void test1()
{
test2();
if (flag) {
// do other stuff
Debug.WriteLine("Initialization OK");
}
else {
Debug.WriteLine("Initialization NOT OK");
}
}
void test2()
{
test3();
if (flag) {
// do other stuff
}
}
void test3()
{
if (xxx)
return;
// do other stuff
flag = true;
}
Related
We have a central STATIC method that get's called from many different locations of our ASP.NET application.
I need to add some conditional logic to the static method that needs to run only if the method was called from a specific class. One approach would be to add an additional parameter to the static method's signature -- some kind of enum that would represent which class called this static method, but I was hoping .NET offered a more elegant approach.
EDIT: See Sample Code below
I am trying to modify how exceptions are handled. Currently, if we are processing 1000 checks, and there is an exception inside the loop at check 500, checks 500 - 1000 will not be processed.
We have several screens on our website that calls this central method. One of them called Check Creation Wizard, another called ACH Creation Wizard, etc. Well for the ACH Creation Wizard, we want to handle exceptions by simply skipping a failed check, and move on to the rest of the checks. However, for all other wizards, we want to continue failing the remaining batch of checks if one fails.
public static string GenerateChecks(List<CheckJob> checkJobs)
{
foreach (CheckJob check in checkJobs)
{
try
{
bool didGenerate = DoGenerate(check);
if(didGenerate)
{
Account acct = LoadAccount(check.GetParent());
ModifyAccount(acct);
SaveAcct(acct);
}
}
catch (Exception ex)
{
if (Transaction.IsInTransaction)
{
Transaction.Rollback();
}
throw;
}
}
}
This all smells from afar. You can have this in many ways, but detecting the calling class is the wrong way.
Either make a different static method for this specific other class, or have an additional argument.
If you insist on detecting the caller, this can be done in several ways:
Use the stack trace:
var stackFrame = new StackFrame(1);
var callerMethod = stackFrame.GetMethod();
var callingClass = callerMethod.DeclaringType; // <-- this should be your calling class
if(callingClass == typeof(myClass))
{
// do whatever
}
If you use .NET 4.5, you can have caller information. Not specifically the class, but you can get the caller name and source file at the time of compilation. Add a parameter with a default value decorated with [CallerMemberName] or [CallerFilePath], for example:
static MyMethod([CallerFilePath]string callerFile = "")
{
if(callerFile != "")
{
var callerFilename = Path.GetFileName(callerFile);
if(callerFilename == "myClass.cs")
{
// do whatever
}
}
}
Simply use an additional parameter with a default value (or any kind of different signature)
Note that 1 is very slow, and 2 is just awful... so for the better yet: use a different method if you need a different process
Update
After watching your code, it's even more clear that you want to have either two different methods or an argument... for example:
public static string GenerateChecks(List<CheckJob> checkJobs, bool throwOnError = true)
{
//...
catch (Exception ex)
{
if(throwOnError)
{
if (Transaction.IsInTransaction)
{
Transaction.Rollback();
}
throw;
}
}
}
And then pass false to that when you want to keep going
You never make a decision on what to do based on who called you. You allow the caller to make that decision by providing a feature.
You want a single method to do two different things on error. So either (1) write two methods, and have the caller decide which one to call, or (2) make the method take a Boolean that changes its behaviour, and have the caller decide which Boolean to pass, true or false.
Adding a parameter is definitely more "elegant". Make the parameter optional (by providing a default value, e.g. bool and false) and only execute the special code if the parameter is explicitly set to true.
The alternative, though not as "elegant" as you can read from the comments, would be to search the StackTrace for the calling code.
I think, you can use StackTrace class, but this logic is not very good
You can use StackTrace like this
static void Main(string[] args)
{
Do();
}
static void Do()
{
DosomethingElse();
}
private static void DosomethingElse()
{
StackTrace stackTrace = new StackTrace();
foreach (StackFrame Frame in stackTrace.GetFrames())
{
Console.WriteLine(Frame);
}
}
and this would be the output
{DosomethingElse at offset 77 in file:line:column <filename unknown>:0:0}
{Do at offset 37 in file:line:column <filename unknown>:0:0}
{Main at offset 40 in file:line:column <filename unknown>:0:0}
....
I'm using an external library load a large and complex file. The call(s) to this library are fairly complex, so I've wrapped them in a couple of static helper methods which nicely take care of caching etc. for me. These methods are then run in the background using Tasks.
During the load process, the library will in some cases throw an Exception stating that a block of the file is malformed and therefore cannot be parsed. These Exceptions are considered "safe", and, if they're swallowed, the library will skip the bad block and happily continue to parse the rest of the file.
When this occurs, I need to show the user a dialog box asking whether or not the file import should be aborted. This works fine as follows:
public static class MyBigFileLoadMethods {
// private fields for locking, caching, etc.
public static Load(string filePath, bool cache = true) {
// validation etc.
try {
var data = LoadMethodInDll(filePath);
} catch (BadBlockException) {
if (MessageBox.Show("boom. continue anyway?") == DialogResult.Yes) {
// call appropriate dll methods to ignore exception and continue loading
} else {
throw;
}
}
}
}
Calling MessageBox.Show() from a method that was designed to be run way in the background feels very wrong, but I haven't come up with a better way that didn't involve so much marshaling and invoking that the code became very difficult to read. Is there a cleaner way to do this or a better way to me to design my loading process?
The appropriate way for a library to do this is via some kind of callback. The simplest implementation would be a delegate returning a bool indicating whether processing should continue. A richer but complicated way would be a policy interface with various methods to implement indicating whether to continue, abort, retry, etc.
Then your UI code provides the callback that shows a message to the user in an appropriate way. Your code to load the library will look like this:
public static class MyBigFileLoadMethods {
// private fields for locking, caching, etc.
public static void Load(string filePath, Func<Exception, bool> continueOnException = null, bool cache = true) {
// validation etc.
try {
var data = LoadMethodInDll(filePath);
} catch (BadBlockException e) {
if (continueOnException != null && continueOnException(e)) {
// call appropriate dll methods to ignore exception and continue loading
} else {
throw;
}
}
}
}
Then in your UI code you will want to marshal back to the UI thread. It will look something like this:
MyBigFileLoadMethods.Load("C:\path\to\data", ShowError);
private bool ShowError(Exception e)
{
if (this.InvokeRequired)
{
return (bool)this.Invoke(new Func<Exception, bool>(ShowError), e);
}
return MessageBox.Show(string.Format("boom: {0}. continue anyway?", e.Message)) == DialogResult.Yes;
}
Greetings everyone!
I have a set of a few (and potentially will have dozens more) of very similar methods in C#. They all built on almost identical pattern:
ResultObjectType MethodX(...input parameters of various types...)
{
nesting preparation code here...
{
{
resultObject = ExternalClass.GetResultForMethodX(input parameters of MethodX);
}
}
nesting result processing code here ...
return resultObject;
}
Repeating/identical parts: ResultObjectType, preparation code, result processing code.
Different parts: ExternalClass method to call, input parameter set (number of input parameters, their types).
Important: I am not in control of the method signatures – cannot change them.
I am trying to avoid repeating all blocks of similar code with something like this:
ResultObjectType MethodX(...input parameters of various types...)
{
return UniversalMethod(
new ExternalMethodDelegate(ExternalClass.GetResultForMethodX),
input parameters of MethodX...);
}
ResultObjectType UniversalMethod (Delegate d, input parameters of various types...)
{
nesting preparation code...
{
{
resultObject =
(d as ExternalMethodDelegate)(same input parameters as above);
}
}
nesting result processing code...
return resultObject;
}
So far I only managed to make it work in this manner in case where all parameters have the same known type at the time of coding. After a number of attempts to tackle this problem with generic delegates I am starting to think this is not possible to achieve. Even when my code compiles, it does not work at runtime. Any takers? Thanks in advance for your help!
Here's an example using generic delegates:
int MethodY(int something, int other)
{
return UniversalMethod(() => GetResultForMethodY(something, other));
}
string MethodX(string something)
{
return UniversalMethod(() => GetResultForMethodX(something));
}
T UniversalMethod<T>(Func<T> fetcher)
{
T resultObject;
//nesting preparation code here...
{
resultObject = fetcher();
}
//nesting result processing code here ...
return resultObject;
}
If ResultObjectType is always the same then you can remove all Ts.
Repeating/identical parts: ResultObjectType, preparation code, result processing code.
You should concentrate to make this parts as isolated as possible.
Another approach is code generation.
This is similar to :
.NET: bool vs enum as a method parameter
but concerns returning a bool from a function in some situations.
e.g.
Function which returns bool :
public bool Poll()
{
bool isFinished = false;
// do something, then determine if finished or not.
return isFinished;
}
Used like this :
while (!Poll())
{
// do stuff during wait.
}
Its not obvious from the calling context what the bool returned from Poll() means.
It might be clearer in some ways if the "Poll" function was renamed "IsFinished()", but the method does a bit of work, and (IMO) would not really reflect what the function actually does. Names like "IsFinished" also seem more appropriate for properties. Another option might be to rename it to something like : "PollAndReturnIsFinished" but this doesn't feel right either.
So an option might be to return an enum. e.g :
public enum Status
{
Running,
Finished
}
public Status Poll()
{
Status status = Status.Running;
// do something, then determine if finished or not.
return status;
}
Called like this :
while (Poll() == Status.Running)
{
// do stuff during wait.
}
But this feels like overkill.
Any ideas ?
A method should be read like a verb, and the result of the bool Poll() method is misleading, and this is probably why it feels awkward to use.
// you wrote.
while( !Poll() )
{
// still waiting .. do something.
}
When I first read your code, I thought it said While (the system is) not polling, do something?
But it really says ... Poll, and if not finished polling do something while we wait.
Your enum version appears to have changed the semantics of the call, but for the better, which is why people like it. While Poll() is still Running, do something while we wait.
The most readable code wins.
I follow the .Net convention that boolean properties are prefixed with "Is" and boolean methods are prefixed with "Try" (or "Is" where appropriate).
In your case I think the problem is in the "Poll" name. Name the method stating what it is doing or polling for. e.g. TryDoSomething()
First of all code is for people to read, and in your case the enum version is more readable than the bool version.
Edit:
Other advantage of enum version is that you can easily add other statuses if you need. Like Error for example.
If you have more than 2 states, use an enum, else just use a bool.
Edit:
As your example, you can easily make use of both, if needed.
public bool IsRunning { get {return Poll() == Running; }}
public bool IsFinished { get {return Poll() == Finished; }}
I read and re-read what you are trying to do. To me, Poll() should mean exactly that you are polling for something. Then I would check the status if it is still running.
My resultant code would look like this.
while (myObject.Poll() && myObject.IsRunning)
{
// myObject successfully poll it ..
// and is successful
// do more things here...
}
Note: IsRunning is a getter/setter. Would this be clearer?
Check out this test:
[TestFixture]
public class Quick_test
{
[Test]
public void Test()
{
Assert.AreEqual(0, GetByYield().Count());
Assert.AreEqual(0, GetByEnumerable().Count());
}
private IEnumerable<string> GetByYield()
{
yield break;
}
private IEnumerable<string> GetByEnumerable()
{
return Enumerable.Empty<string>();
}
}
When I write stub methods I generally use the Enumerable.Empty way of doing it. I stumbled across some old code I wrote where I did it the yield way.
This got me to wondering:
Which is more visually appealing to other developers?
Are there any hidden gotchas that would cause us to prefer one over the other?
Thanks!
I would prefer any method that delivers the clearest meaning to the developer. Personally, I don't even know what the yield break; line is does, so returning 'Enumerable.Empty();` would be preferred in any of my code bases.
Enumerable.Empty : the documentation claims that it "caches an empty sequence". Reflector confirms. If caching behavior matters to you, there's one advantage for Enumerable.Empty
Even faster might be:
T[] e = {};
return e;