A method declared with a return type such as:
intpromises its caller an integer result.
For example:
public int GetGoalCategory()
{
return 1;
}The caller expects the method to produce an int.
When a method contains conditional paths, each possible path must still lead to a valid result.
Consider:
public string GetAvailabilityText()
{
if (this.isAvailable)
{
return "Available";
}
}There is a problem.
When:
isAvailable = truethe method returns a string.
When:
isAvailable = falseexecution can reach the end of the method without returning the promised string.
That leaves one code path without a result.
A complete version is:
public string GetAvailabilityText()
{
if (this.isAvailable)
{
return "Available";
}
else
{
return "Unavailable";
}
}Now both possible paths produce a string.
Conceptually:
isAvailable?
├─ true → return "Available"
└─ false → return "Unavailable"Every path sends a result to the caller.
When reviewing a returning method with a decision, do not inspect only the branch you expect most often.
Trace:
For each path, ask:
Consider:
public string GetGoalCategory(int goals)
{
if (goals >= 3)
{
return "High scoring";
}
else if (goals == 2)
{
return "Two goals";
}
else
{
return "Fewer than two";
}
}The final else provides a result when neither earlier condition is true.
Every branch returns a string.
Another pattern is:
public string GetGoalCategory(int goals)
{
if (goals >= 3)
{
return "High scoring";
}
return "Fewer than three";
}If the first condition is true, the first return executes.
If it is false, execution continues to the final return.
Both paths produce a string.
A void method does not promise a data value:
public void DisplayScore()
{
System.Console.WriteLine(this.score);
}It can finish without returning a value.
A non-void method does promise a result:
public int GetScore()Its valid execution paths must produce an integer result.
The return type changes what the method is required to provide.
For:
public int GetScore()this is compatible:
return this.score;A string such as:
return "three";does not match the declared integer result.
Completeness and type compatibility both matter.
For a simple method:
public string GetAvailabilityText()
{
if (this.isAvailable)
{
return "Available";
}
else
{
return "Unavailable";
}
}you can reason with:
| Condition | Path | Returned value | | --- | --- | --- | | isAvailable == true | if | "Available" | | isAvailable == false | else | "Unavailable" |
Every possible condition result has a returned string.
Suppose a returning method contains a nested decision.
Do not assume that one return somewhere inside the nested structure covers the entire method.
Trace each possible combination of reached branches.
The question remains:
When C# reports that not all code paths return a value, inspect the method's conditional structure.
The message is telling you that at least one possible execution path can finish without providing the declared result.
Do not silence the message by adding an arbitrary return value.
Choose a return that matches the requirement.
If a method is supposed to classify a score, each returned value should describe the correct category.
A method that returns something on every path can still be logically wrong.
You need both:
For a non-void method:
A returning method is complete only when every valid execution path produces the promised result.