Unreachable code and not all code paths return a value - c#

Ok I'm getting an unreachable code and not all code paths return value from this block of code
private string MoveForward()
{
//if current direction is east, GetRoomEast
if (Player.CurrentDirection == "EAST")
{
return GetroomEast();
if (Player.NextMove != "")
{
Player.Y++;
}
else
{
Console.WriteLine("You Bumped into a Wall");
}
//if GetRoomEast is not "", then playercol = playercol+1;
//if current direction is west...
}
}
and my initialized variables at the top are
public struct DragonPlayer
{
public int X, Y;
public string CurrentDirection;
public string NextMove;
}
public class DragonGameboard
{
public string[,] GameboardArray;
public DragonPlayer Player;
private Random r;
public DragonGameboard()
{
GameboardArray = new string[4, 4];
Player.CurrentDirection = "EAST";
Player.NextMove = "";
r = new Random();
Player.X = r.Next(0, 4);
Player.Y = r.Next(0, 4);
GenerateRandomBoard();
}
}
Why is it doing this? I'm sure it has to be something really silly but I'm having trouble figuring out what it is?

You are returning from your function before your if statement,it's never going to your if statement.Therefore your if statement become unreachable code
return GetroomEast();
if (Player.NextMove != "")
You should put this return statement after the if statement.

You defined your MoveForward() forward method to return a string, but you're not returning one. Change the definition to:
private void MoveForward();
...or return a string.

Every path of your code has to return value of type string. Plus you have code that can never execute, namely:
if (Player.NextMove != "")
{
Player.Y++;
}
else
{
Console.WriteLine("You Bumped into a Wall");
}
You've already returned a value, so nothing after that gets executed.
Furthermore, every path that results in ending of the function HAS TO return a value. Go through your code logically and find the scenarios, you'll find plenty.
Maybe I'd suggest to start slow and learn the basics, because these mistakes are really fundamental to any programming language + you already got the message, that is pretty clear. Programming games isn't really a good starting point for programmers.

I have added comments in the code to show you why have unreachable code and why all code paths do not return a value.
private string MoveForward()
{
if (Player.CurrentDirection == "EAST")
{
return GetroomEast(); //Once you return the value here it ends the call.
if (Player.NextMove != "") //This line (or anything below it) will never run.
{
Player.Y++;
}
else
{
Console.WriteLine("You Bumped into a Wall");
}
//if GetRoomEast is not "", then playercol = playercol+1;
//if current direction is west...
}
//We reach here if Player.CurrentDirection does not equal "EAST"
//As there is no more code there is no returned value.
//You would need to do something like return NoValidMove()
}

After this line, return GetroomEast() the execution is bailed out of the loop and hence, u are getting unreachable code error. Also nothing is returned inside the next if , else blocks. As your method is of string return type....it has to return string..

Related

Getting "not all code paths return a value" for code that will never not return a value

The method I write doesn't return a value though I write every possible conditions to return a value.
What I understand is whenever the compiler sees the return keyword it'll stop, execute the program and return the value next to the return keyword. Even if it is in the loop it'll break the loop and return the value but it the compiler shows the "not all code paths return a value" error. And there's an else conditions for the other possible conditions and how comes the error show up.
So, how the return keyword actually work?
I am so confused.
using System;
public static class PhoneNumber
{
public static (bool IsNewYork, bool IsFake, string LocalNumber) Analyze(string phoneNumber)
{
bool flag = true;
string[] numSub = phoneNumber.Split("-");
while(flag)
{
if(numSub[0] == "212")
{
if(numSub[1] == "555")
{
return (true, true, numSub[2]);
}
else{return (true, false, numSub[2]);}
} // end of if condition
else{
if(numSub[1] == "555")
{
return (false, true, numSub[2]);
}
else{return (false, false, numSub[2]);}
} // end of the else condition
} // end of the loop
}
not all code paths return a value
The compiler is not "smart" enough to know that you will enter the while loop. So it sees the code path that doesn't enter the while loop as a possible code path without a return.
As-written the code structure doesn't make much sense, so it should probably be restructured to make the compiler happy, and be easier to read and maintain. You can also just a thrown exception after the while to get rid of the compilation error.

is it possible to move my return values around in this method?

I'm writing a code to create a new object with key metadata being provided by a user input form. I'm wondering if there's a way to return the object (q) in the try block and not at the end of the method?
Here's my current code with some notes about how I want it all to look:
public NewSearchQuery GetEntry()
{
//pull all input field information and store ready for validation
string name = Convert.ToString(Companies.SelectedItem);
string location = String.Concat(Convert.ToString(Property.Text), " ", Convert.ToString(SearchLocation.Text).ToLower());
string searchtype = Convert.ToString(Search.SelectedItem);
var q = new NewSearchQuery();
//check all required input fields are filled in
if (String.IsNullOrEmpty(name) || String.IsNullOrEmpty(location) || String.IsNullOrEmpty(searchtype))
{
MessageBox.Show("Please ensure you have filled in all the required fields (*) before proceeding", "Insufficient Information");
this.ShowDialog();
}
else
{
try
{
q.GetFormData(name, location, searchtype, Paid.Checked); //replace this with a constructor for var q
q.Contract = ThisAddIn.GetContract(q.Name);
q.CreateIdNum();
q.CreateFilePath(q.Contract, q.RefNum);
q.CalculateFees();
}
catch (Exception d)
{
MessageBox.Show(Convert.ToString(d)); //return null if the try fails
}
}
return q; //relocate this to the try block
}
I want to make these changes because I suspect that returning the q value irrespective of the process working or not is causing my winform to error out it if try to exit it prematurely.
Is there a way I can get around the inevitable 'not all code paths return a value' error?
You can rewrite your method as follows:
public NewSearchQuery GetEntry()
{
//pull all input field information and store ready for validation
string name = Convert.ToString(Companies.SelectedItem);
string location = String.Concat(Convert.ToString(Property.Text), " ", Convert.ToString(SearchLocation.Text).ToLower());
string searchtype = Convert.ToString(Search.SelectedItem);
//check all required input fields are filled in
if (String.IsNullOrEmpty(name) || String.IsNullOrEmpty(location) || String.IsNullOrEmpty(searchtype))
{
MessageBox.Show("Please ensure you have filled in all the required fields (*) before proceeding", "Insufficient Information");
this.ShowDialog();
return null;
}
try
{
var q = new NewSearchQuery();
q.GetFormData(name, location, searchtype, Paid.Checked); //replace this with a constructor for var q
q.Contract = ThisAddIn.GetContract(q.Name);
q.CreateIdNum();
q.CreateFilePath(q.Contract, q.RefNum);
q.CalculateFees();
return q;
}
catch (Exception d)
{
MessageBox.Show(Convert.ToString(d)); //return null if the try fails
return null;
}
}
Now all code paths return a value. I omitted the else block, because if you leave the method inside the if block. This means, that the code following the if block is never executed when your condition is true, as it would be with the else block. The advantage of this is that you don't have so much nested bracings, which makes the code easier to understand.
Be sure to check whether the return value is not null, otherwise you might have a NullReferenceException.
Yes,
Write a return statement within every single block.
if(something)
{
return value;
}
else
{
try
{
return value;
}
catch
{
return value;
}
}

Elegant way to prevent StackOverflow in Recursion

I'm trying to port this Genetic Algorithm,
and I made a recursive function for advancing from one generation to another.
However, as I'm new to recursion in C# (and in general), I evidently bumped into StackOverflowException when there were too many generations (more than around 4500).
In order to solve the problem, I made Generation() return a bool, so when the genetic algorithm reachs max fitness (goal), it returns true. Else it returns Generation().
If it's about to overflow (Generation > 4500), it returns false.
Now In Main(), to keep Generation() running until it returns true, I use a while loop, so it will start over the recursion until it completes.
This is way more efficient than doing Task.Run, so I went for this approach.
Is this good practice? Are there any more elegant ways of preventing StackOverflows without sacrificing performance?
Population.cs:
class Population
{
public int GenerationNumber { get; private set; }
public int TotalGenerationNumber { get; private set; }
public const int StackGenerationLimit = 4500;
public Population()
{
GenerationNumber = 0;
TotalGenerationNumber = 0;
}
public bool Generation()
{
// Work
// if(HasReachedGoal) return true;
GenerationNumber++;
if(GenerationNumber > StackGenerationLimit)
{
return false;
} else
{
return Generation();
}
}
public void ResetStack()
{
TotalGenerationNumber += GenerationNumber; // I store the total number of generation for information purposes
GenerationNumber = 0; // Reset the recursion depth value
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
Population population = new Population();
while (!population.Generation()) // Until it reaches its goal
{
population.ResetStack();
}
Console.WriteLine("End. Generations: " + population.TotalGenerationNumber);
}
}
The best way to avoid stack overflow is to not use recursion. You're already half way to the answer with your workaround. Now you just need to ask yourself the question of what you gain from recursion any more? If your return Generation(); statement in the Generation function were instead changed to return false; then you would go back to the main loop where it would call Generation() again.
Of course having made this change there are now a lot of other tidy ups you can do. You no longer need your stack reset, you no longer need the if statement that checks for the generation limit and all your repetitions are done from the while loop.
So your two methods:
public bool Generation()
{
TotalGenerationNumber++;
// Work
return HasReachedGoal;
}
static void Main(string[] args)
{
Population population = new Population();
bool hasCompleted = false;
while (!hasCompleted) // Until it reaches its goal
{
hasCompleted = population.Generation();
}
Console.WriteLine("End. Generations: " + population.TotalGenerationNumber);
}
Note that in the tidyup I've introduced a bool variable called hasCompleted since I find it more readable to use a variable for the while condition and prefer to have the work inside the loop itself.
I think in this case, you would be better off preping the while loop and sending in the data you want to check into the .Generation call. then if it returns false, you update the data. Something like this:
Population population = new Population();
var input = new InputDto() { ... };
while (!population.Generation(input)) // Until it reaches its goal
{
// update input
}
This prevents a too deeply nested call that gets the error you are describing.

How to call a non static method from static method

I need to call a non static method from a static[webmethod]. It is not getting call, I tested it using breakpoints.i tried to call it by making a instance to the class.
This is what i am trying .
[WebMethod]
public static string get_runtime_values(string get_ajax_answer_title,string get_ajax_answer_des)
{
if (get_ajax_answer_title.Equals("") && (get_ajax_answer_title.Equals("")))
{
return "null";
}
else
{
int got_question_id = getting_question_id;
DataHandler.breg obj = new DataHandler.breg();
obj.add_anwers(got_question_id, get_ajax_answer_title, get_ajax_answer_des);
return "inserted";
}
querystring object_new = new querystring();
object_new.show();
}
querystring is name of the class here.The control is going into if and else statements depending upon input,but after that it directly get jump out.Moreover when i hover the mouse over querystring ,it says
Unreachable code detected.
What should I do to make it working?
That's because you return from both halves if the preceding if statement.
There is no way for it to get up to that line.
It's because you have a return statement in both the IF and ELSE section.
So regardless of the result of the conditional; you never get below that.
Your method ends after the if statement, wether it is true (return "null") or not (return "inserted"). So your code that is after the if statement (where you create the query string) can never be executed.
[WebMethod]
public static string get_runtime_values(string get_ajax_answer_title,string get_ajax_answer_des)
{ string result;
if (get_ajax_answer_title.Equals("") && (get_ajax_answer_title.Equals("")))
{
result="null";
}
else
{
int got_question_id = getting_question_id;
DataHandler.breg obj = new DataHandler.breg();
obj.add_anwers(got_question_id, get_ajax_answer_title, get_ajax_answer_des);
result="inserted";
}
querystring object_new = new querystring();
object_new.show();
return result;
}
Your problem is that you are exiting your method in both your if and else clauses. Your code is essentially:
MyMethod()
{
if (someCondition)
return
else
return
// Any code at this point cannot be executed, because
// you have definitely returned from your method.
}
querystring object_new = new querystring();
object_new.show();
part will never be reached because in both of your block statement in your condition you wrote a return.
Yes, that is because you have return statements at the end of both your if and else blocks.
Change it to
[WebMethod]
public static string get_runtime_values(string get_ajax_answer_title,string get_ajax_answer_des)
{
string ret = "null";
if (!get_ajax_answer_title.Equals("") || (!get_ajax_answer_title.Equals("")))
{
int got_question_id = getting_question_id;
DataHandler.breg obj = new DataHandler.breg();
obj.add_anwers(got_question_id, get_ajax_answer_title, get_ajax_answer_des);
ret = "inserted";
}
querystring object_new = new querystring();
object_new.show();
return ret;
}
Unreachable code detected. is because both paths of your if statement return early.
if (get_ajax_answer_title.Equals("") && (get_ajax_answer_title.Equals("")))
{
return "null"
}
else
{
return "inserted";
}
// Can't get here.
You have answered your original question correctly, i.e. Instantiate an instance of a non-static method to be able to call a method on it.
querystring object_new = new querystring();
object_new.show();

Returning the first method that works, more elegant way?

Recently I've found myself writing methods which call other methods in succession and setting some value based on whichever method returns an appropriate value first. What I've been doing is setting the value with one method, then checking the value and if it's not good then I check the next one. Here's a recent example:
private void InitContent()
{
if (!String.IsNullOrEmpty(Request.QueryString["id"]))
{
Content = GetContent(Convert.ToInt64(Request.QueryString["id"]));
ContentMode = ContentFrom.Query;
}
if (Content == null && DefaultId != null)
{
Content = GetContent(DefaultId);
ContentMode = ContentFrom.Default;
}
if (Content == null) ContentMode = ContentFrom.None;
}
Here the GetContent method should be returning null if the id isn't in the database. This is a short example, but you can imagine how this might get clunky if there were more options. Is there a better way to do this?
The null coalescing operator might have the semantics you want.
q = W() ?? X() ?? Y() ?? Z();
That's essentially the same as:
if ((temp = W()) == null && (temp = X()) == null && (temp == Y()) == null)
temp = Z();
q = temp;
That is, q is the first non-null of W(), X(), Y(), or if all of them are null, then Z().
You can chain as many as you like.
The exact semantics are not quite like I sketched out; the type conversion rules are tricky. See the spec if you need the exact details.
You could also do something a little more sneaky, along the lines of this:
private Int64? GetContentIdOrNull(string id)
{
return string.IsNullOrEmpty(id) ? null : (Int64?)Convert.ToInt64(id);
}
private Int64? GetContentIdOrNull(DefaultIdType id)
{
return id;
}
private void InitContent()
{
// Attempt to get content from multiple sources in order of preference
var contentSources = new Dictionary<ContentFrom, Func<Int64?>> {
{ ContentFrom.Query, () => GetContentIdOrNull(Request.QueryString["id"]) },
{ ContentFrom.Default, () => GetContentIdOrNull(DefaultId) }
};
foreach (var source in contentSources) {
var id = source.Value();
if (!id.HasValue) {
continue;
}
Content = GetContent(id.Value);
ContentMode = source.Key;
if (Content != null) {
return;
}
}
// Default
ContentMode = ContentFrom.None;
}
That would help if you had many more sources, at the cost of increased complexity.
Personally, I find when I have lots of statements that are seemingly disparate, it's time to make some functions.
private ContentMode GetContentMode(){
}
private Content GetContent(int id){
}
private Content GetContent(HttpRequest request){
return GetContent(Convert.ToInt64(request.QueryString["id"]));
}
private void InitContent(){
ContentMode mode = GetContentMode();
Content = null;
switch(mode){
case ContentMode.Query:
GetContent(Request);
break;
case ContentMode.Default:
GetContent(DefaultId);
break;
case ContentMode.None:
... handle none case...
break;
}
}
This way, you separate your intentions - first step, determine the content mode. Then, get the content.
I suggest you try some kind of Factory design pattern for this case. You can abstract the content create procedure by register different creators. Moreover, you can add preference on each creator for your own logic. Besides, I suggest you encapsulate all data related to Content just like "ContentDefinition" class from other's post.
In general, you need to know that there is always a trade off between flexibility and efficiency. Sometime your first solution is good enough:)
Ok, because I noticed a bit late that you actually wanted the ContentFrom mode as well, I've done my best to come up with a translation of your sample below my original answer
In general I use the following paradigm for cases like this. Search and replace your specific methods here and there :)
IEnumerable<T> ValueSources()
{
yield return _value?? _alternative;
yield return SimpleCalculationFromCache();
yield return ComplexCalculation();
yield return PromptUIInputFallback("Please help by entering a value for X:");
}
T EffectiveValue { get { return ValueSources().FirstOrDefault(v => v!=null); } }
Note how you can now make v!=null arbitrarily 'interesting' for your purposes.
Note also how lazy evaluation makes sure that the calculations are never done when _value or _alternative are set to 'interesting' values
Here is my initial attempt at putting your sample into this mold. Note how I added quite a lot of plumbing to make sure this actually compiles into standalone C# exe:
using System.Collections.Generic;
using System.Linq;
using System;
using T=System.String;
namespace X { public class Y
{
public static void Main(string[]args)
{
var content = Sources().FirstOrDefault(c => c); // trick: uses operator bool()
}
internal protected struct Content
{
public T Value;
public ContentFrom Mode;
//
public static implicit operator bool(Content specimen) { return specimen.Mode!=ContentFrom.None && null!=specimen.Value; }
}
private static IEnumerable<Content> Sources()
{
// mock
var Request = new { QueryString = new [] {"id"}.ToDictionary(a => a) };
if (!String.IsNullOrEmpty(Request.QueryString["id"]))
yield return new Content { Value = GetContent(Convert.ToInt64(Request.QueryString["id"])), Mode = ContentFrom.Query };
if (DefaultId != null)
yield return new Content { Value = GetContent((long) DefaultId), Mode = ContentFrom.Default };
yield return new Content();
}
public enum ContentFrom { None, Query, Default };
internal static T GetContent(long id) { return "dummy"; }
internal static readonly long? DefaultId = 42;
} }
private void InitContent()
{
Int64? id = !String.IsNullOrEmpty(Request.QueryString["id"])
? Convert.ToInt64(Request.QueryString["id"])
: null;
if (id != null && (Content = GetContent(id)) != null)
ContentMode = ContentFrom.Query;
else if(DefaultId != null && (Content = GetContent(DefaultId)) != null)
ContentMode = ContentFrom.Default;
else
ContentMode = ContentFrom.None;
}

Categories

Resources