I'm new to C# and while coding a small function facing this weird problem. While using the return statement I want to return to the calling function but instead it takes me to a level before in the recursion and never exits from the recursive function.
My code is as follows:
private void findrel(String from, String to, List<RelAttr> relation)
{
String var;
List<RelAttr> temp = new List<RelAttr>();
for (int i = 0; i < relation.Count; i++)
{
if (Some Condition)
{
if (Another Condition)
{
//Do Something
paths.Add(Something);
return;
}
else
{
//Capture some value in var
paths.Add(Something);
//Move to Temp
temp.AddRange(relation);
//Remove Active Entry From Temp
temp.RemoveAt(i);
//Call with Newlist (temp)
findrel(var, to, temp);
}
}
}
//Remove Last Entry when recursion unwinds
paths.RemoveAt(paths.Count - 1);
}
I'm calling this function normally from the other function such as:
findrel(from, to, relations);
And I want the return statement to return to this function and not to a level before in the recursion. Any ideas?
The return statement will always return to the caller, and when you are using recursion this will include returning to the level above, and will not jump back to the original caller.
If you want to get right out of findrel then you will have to do something like return a flag so that the previous level knows that it should just return back to its caller and not do any more processing.
So the code will still unwind from all the calls to findrel but you will have effectively stopped processing.
Usually with recursive functions you have a terminating condition and that causes all levels of the returning function to return and this will return you to the caller. One suggestion might be to return a Boolean and terminate the recursion if that value is say false. The you can add that condition to the terminating condition of your loop and your function will exit all levels.
Related
I have a loop inside a C# method that has the following structure.
do
{
getUserInput();
if (inputIsBad)
{
doSomethingElse();
}
} while (inputIsBad);
alternately, with a while loop:
getUserInput();
while (inputIsBad)
{
doSomethingElse();
getUserInput();
}
But both methods use redundant code: the do-while has both an if statement and while loop checking the same condition; the while loop calls getUserInput() both before and inside the loop.
Is there a simple, non-redundant, non-ad hoc way to do what these method patterns do, either generally or in C# specifically, that only involves writing each basic component once?
Assuming that getUserInput(..) can be converted into a expression yielding a boolean value*..
while (getUserInput()
&& isBadInput()) {
doSomethingElse();
}
// Prompts for user input, returns false on a user-abort (^C)
private bool getUserInput() { .. }
Other variations (presumed without non-local state) shown in comments.
*Trivially, it can always be written as a wrapping function - see Local Functions, introduced in C#7. (There are other methods for the same effect, some of which I consider 'too clever'.)
// local function
bool getUserInputAlwaysTrue() {
getUserInput(); // assume void return
return true;
}
while (getUserInputAlwaysTrue()
&& isBadInput()) {
doSomethingElse();
}
This can be followed to pushing out the logic further, in some cases. The general premise holds: getUserInput() is always invoked prior to the next isBadInput().
// local function or member method
// Prompt for user input, returning true on bad input.
bool getCheckedUserInput() {
getUserInput(); // assume void return
return isBadInput();
}
while (getCheckedUserInput()) {
doSomethingElse();
}
do
{
getUserInput();
if (!inputIsBad) break;
doSomethingElse();
} while (true);
I would use a boolean variable, which you need to declare outside the body of the loop. That way you only need to run the inputIsBad check once. I have turned it into a method as well, since that seems more logical.
bool badInput = true; // Assume bad until checked -- failsafe.
do
{
getUserInput();
badInput = inputIsBad();
if (badInput)
{
doSomethingElse();
}
} while (badInput);
Building on user2864740's answer:
Assume getUserInput() can be converted into a function which returns true if the input is good and bad otherwise. Assuming its original return type wasn't boolean or void, return its original return value via an out or ref parameter depending on the case, e.g.
int originalReturnValue;
while (!getUserInput(out originalReturnValue))
{
doSomethingElse();
}
...
bool getUserInput<T>(out T output)
{
// method body
}
So I'm slowly reading my way through a work book and have come to the section on enumerators. During which it gives the example code of
public class GameMoves
{
private IEnumerator _cross;
private IEnumerator _circle;
private int i;
public GameMoves()
{
_cross = Cross();
_circle = Circle();
i = I();
}
private int _move = 0;
const int MaxMoves = 9;
public int I()
{
Console.WriteLine("Test");
return (1);
}
public IEnumerator Cross()
{
while (true)
{
WriteLine($"Cross, move {_move}");
if (++_move >= MaxMoves)
{
yield break;
}
yield return _circle;
}
}
public IEnumerator Circle()
{
while (true)
{
WriteLine($"Circle, move {_move}");
if (++_move >= MaxMoves)
{
yield break;
}
yield return _cross;
}
}
}
I run this from the main method and create a new instance of this class. When the constructor runs _cross = Cross(); I expected it to work similarly to i = I(); i.e. run through the class and take the returned value. When I step through the program, it doesn't seem to activate the Cross() class at all, instead that line creates an enumerator with the value of null. Just wondering if someone could explain what that step is doing. Thanks
The whole point of iterators is exactly what you're seeing. An iterator is supposed to defer execution until the results are actually used. In your code, the I method is not an iterator so its body is executed to completion when you call it. The Cross method is an iterator so its body doesn't get executed until you use the result.
For instance, if you were to use a foreach loop to enumerate _cross you would see that each iteration of the loop would cause a yield keyword to be hit inside the Cross method. Once the yield break is hit, the method has completed and your loop would exit.
As an example of why this is good, let's compare the File.ReadAllLines method and the File.ReadLines method. The former has been around since .NET 1.0 while the latter is a much later addition. The ReadAllLines method reads the entire file and breaks it up into lines, then returns an array containing those lines. That means that you cannot start processing the file until its entire contents has been read. It also means that you must read the entire contents even if you don't need it. For instance, if there were a million lines and you wanted the first one containing a particular word, you'd have to read every line even if you found the word in the tenth line.
By contrast, the ReadLines method is an iterator. It doesn't start reading the file until you actually need the data and it only reads the data as it's needed. That means that you can process the data as it's read rather than waiting until it's all been read to start processing. It also means that you don't have to read any more data than is required, e.g. if you start looking for a word and find it on the tenth line, the remaining 999,990 lines will not be read.
Could anyone help me out by providing the solution through Recursive Methods
My Requirement is I want a recursive method, that needs to run the below code three times:
Below is my C# Working Code :
public void Process()
{
bool exists = File.Exists("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\RevisionNumber.txt");
for(int i = 0; i < 3 && exists; i++)
{
System.Diagnostics.Process.Start("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\SvnUninstallation.exe");
Sleep(2000); // or long enough to ensure the uninstall process finishes executing
exists = File.Exists("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\RevisionNumber.txt");
}
Console.WriteLine(exists);
Console.ReadLine();
}
Your original code, with the for loop, does exactly what your recursive function will do. I am not too happy with posting this code. The only valid time I could think of using a recursive function, is when you are building up a Tree structure of some sorts.
You should also be aware, if you do not implement a recursive function properly, and you do not break the continuous loop you might create using recursive functions, you will run into an StackOverflow exception, due to your method being called is added to the stack, and the stack will eventually run out of memory.
Here is one way of implementing a recursive function for your needs:
public void Process(int count = 0)
{
bool exists = File.Exists("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\RevisionNumber.txt");
if (exists && count < 3)
{
System.Diagnostics.Process.Start("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\SvnUninstallation.exe");
Thread.Sleep(2000); // or long enough to ensure the uninstall process finishes executing
//File exists
Console.WriteLine("File exists");
Process(++count);
}
else
{
Console.WriteLine("Exceeded retry of 3 times. File did not uninstall.");
}
if (!exists)
Console.WriteLine("File uninstalled");
}
Here is the code snippet for Recursive Method. Try it and let me know if you have any queries.
static bool FileExists(bool _fileexists, int Count)
{
//Console.WriteLine("Inside File Check");
Count++;
System.Diagnostics.Process.Start("C:\\Users\\sk185462\\Desktop\\SVNUPDATED\\SvnUninstallation.exe");
Thread.Sleep(2000);
return (_fileexists == false && Count <=3) ? FileExists(File.Exists("C:\\IFRToolLog1.txt"),Count) : true;
}
I have a method that i have to call it from itself for multiple times in order to get a result and i want to know is Recursive call work as goto in this situation ?
Dummy Code:
public int DummyMethod()
{
string token;
int result = -1;
token = GetNewToken();
Stopwatch stopwatch = Stopwatch.StartNew();
while (result == -1)
{
if (stopwatch.Elapsed >= TimeSpan.FromSeconds(350)) {
//This is related to some logic as the token for the website
//expires after 350 seconds.
result = DummyMethod();
continue; //DO I NEED TO USE contunue ? or the recursive
//call broke the method (as if i used goto)
}
result = GetResultFromWebSite(token);
}
return result;
}
I think you have this all wrong and you definitely shouldn't be trying to figure out if your token has expired. This should be something the server tells you. If it comes via an exception you could do something like this:
public int DummyMethod(int retries = 0)
{
string token;
try
{
token = GetNewToken();
return GetResultFromWebSite(token);
}
catch (Exception e)
{
if (retries < 4) // or whatever max you want - you probably shouldn't hardcode it
{
return DummyMethod(++retries);
}
throw new Exception("Server ain't responding");
}
}
In a situation like this, it's often a good idea to have a maximum number of retries after which you will give up and show an error message.
You should instead use
return DummyMethod();
which is a tail call (the compiler can turn it into a goto).
This is a good illustration of one way the "single entry/single return" mantra fails.
However, I'm pretty sure you could just build this into the loop and avoid recursion:
public int DummyMethod()
{
Stopwatch stopwatch = Stopwatch.StartNew();
string token = GetNewToken();
int result;
do
{
if (stopwatch.Elapsed.TotalSeconds >= 350) {
token = GetNewToken();
stopwatch.Restart();
}
result = GetResultFromWebSite(token);
} while (result == -1);
return result;
}
It seems to me that you want to know how to stop the recursion. This is normally done with a condition where the result is clear and returned without calling the recursive function again. This way the endless calling of the recursive method is stopped and the recursion will come to an end. You dont use a goto for that like you simply never should use goto ;)
No, recursive calls are not equivalent to goto statements.
You don't even need to use recursion to solve your problem. If you place your call to GetNewToken in the loop, you can check the result and use continue to perform another iteration if you don't get the desired results. If you do get the desired result, you can call GetResultFromWebSite and return its result immediately.
What is the difference between saying:
if (abc == "a")
{
// do something here...
return;
}
and the same as above, but without the return keyword?
I am a C# coder and I know that the return keyword followed by a type or variable returns that item, but in the above context, return seems to be just to exit the code block but does it make any functional or performance change on the code?
Thanks
"return" exits from the function, not just the enclosing code block. So if your code block was in the context of a function, like so (I don't know C# so I'm using Java syntax):
int thisIsAFunction(int a) {
if (abc == "a")
{
// do something here...
return 1;
}
// do something else here...
}
if abc == "a" then the "do something else here" will not run. But if you removed the return statement inside the if block, then it would run.
return statement exits the function immediately, so it might have performance benefits as the following code in the function would not be executed at all.
MSDN
The return statement terminates execution of the method in which it appears and returns control to the calling method. It can also return an optional value. If the method is a void type, the return statement can be omitted.
Example
//this would do nothing
public void method()
{
return;
}
//this would return true
//notice the return type of bool this means
//the method expects a true\false value
public bool method2()
{
return true;
}
public void test()
{
if(method2())
method()
}
Now if you ran test method2 would always return true and method1 would just end its processing
The return statement does exit the current method, not just the code block (for/while/if/etc). So it is useful for situations like the following:
public void MyMethod(object myObject)
{
if (myObject == null)
{
return; // exits method.
}
// do something with myObject
}
Additional info: I will point out, that many people prefer to have one exit point in a method, however, it can be useful to do something similar to the example here in some cases. I would always try to find ways to limit the number of return or exit points in your method.
In your case, no - but if you had other code after your 'if' statement that you only wanted to run if your statement was false (e.g. if abc != "a"), then the return allows you to bypass that and exit the function / method.
In a loop or case statement, you can use break to achieve this result. This doesn't work on if statements or code blocks in general though.
And yes, return exits the enclosing function.
Executing the return statement will make the execution jump out of the method. Without the return, it would simply go on with the next statement instead.
Yes, your method does not have return type in this case.
e.g.
public void Foo
{
if (abc == "a")
{
// do something here...
return;
}
// some other code
}
This is to say if abd = "a", then exit the method so that some other code won't be executed.
It can be a cleaner way of writing code. I typically do it in a guard clause at or near the beginning of a method. If you have an error condition, just "return" out of the method. It saves wrapping the rest of your work in an else block. Seems trivial, but it helps to reduce code complexity.