I am still new to C# and trying to resolve this issue here. I have a method with an int
return type, and when I add error message, I get an error and the code doesn't compile.
private static int GetNum(CAP cap)
{
List<Error> errors = new List<Error>();
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
// this line of code causes the error
return errors.Add(new Error("Unit not found"));
}
else
{
return int.Parse(unitNumber.AccessAddress);
}
}
Please tell me what I can do to resolve this.
CodePudding user response:
I'd suggest you throw an exception instead of returning an Error
.
private static int GetNum(CAP cap)
{
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
throw new IndexOutOfRangeException("Unit not found");
}
return int.Parse(unitNumber.AccessAddress);
}
You might additionally, change the function name to GetUnitNumber
. Then I'd think about why CAP
instances exist with missing values for "UnitNumbers"
in the pointsAddress
collection.
CodePudding user response:
Your error arises because you specify the return type of your method as int
and you are trying to return the return value of the method Add
inside the if clause. Add
s return type is void, so it does not return anything, which is in conflict to the expected int
.
It seems to me that a "TryDoSomeThing" pattern is what you are trying to implement.
In this case you should return a bool
to signal whether the procedure has succeeded, and return the real value or the error messages via out
.
private static bool TryGetNum(CAP cap, out int num, out List<Error> errors)
{
int num = -1; // choose a default value here
List<Error> errors = new List<Error>();
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
errors.Add(new Error("Unit not found")); // add your error messages
return false;
}
else
{
num = int.Parse(unitNumber.AccessAddress); // this will be accessible from the out parameter
return
}
}
Using it similarly like the TryParse
methods you could call it like this:
bool result = TryGetNum(cap, out int num, out List<Error> errors);
if(result)
{
// use num here
}
else
{
// use errors here
}
CodePudding user response:
Add
returns nothing (i.e. void
), it can't be transformed into int
. If you want to return some kind of Either
type you can return a value tuple:
private static (int? Value, List<Error>? Errors) GetNum(CAP cap)
{
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
List<Error> errors = new List<Error>();
errors.Add(new Error("Unit not found"));
return (null, errors);
}
else
{
return (int.Parse(unitNumber.AccessAddress), null);
}
}
And then check the return:
var (val, errors) = GetNum(...);
if(val.HasValue)
{
.... // Use value
}
else
{
// Do something with errors
}
CodePudding user response:
In simple Words a void
Method is a Method that does a Action without returning a value, therefore when you ask it for a value such as int
it gives you a parsing exception, i'd suggest doing something like this:
private static int GetNum(CAP cap)
{
List<Error> errors = new List<Error>();
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
var error = new Error("Unit not found");
errors.Add(error);
//Creating the Error and puting in the list is just writen here right now because i was not sure if you in some way need that to happen, in other words you can remove it if you don't need it
throw new IndexOutOfRangeException("Unit not found");
}
else
{
return int.Parse(unitNumber.AccessAddress);
}
}
CodePudding user response:
The method Add()
returns void. When using the output of Add()
as the return value for your method, you are trying to output a void
value in an int
method.
A quick solution for this would be to make the method nullable and then returning a null int, like this:
private static int? GetNum(CAP cap) // Notice the ? after the type, this means it can also be null
{
List<Error> errors = new List<Error>();
var unitNumber = cap.pointsAddress["UnitNumbers"];
if (unitNumber == null)
{
errors.Add(new Error("Unit not found")); // this create the error
return null;
}
else
{
return int.Parse(unitNumber.AccessAddress);
}
}
CodePudding user response:
your expectation :
- return error message when there is null/empty
- return int
root cause : return type must match method signature declaration.
suggestion : you probably violating Single Responsibilty principal. your method should only do 1 thing, return the value of CAP object. let the caller handle exceptional case.
There are multiple ways to solve your problem, and it is hard to suggest which one is best depends on the usage context.
- Throw exception. can treat null, empty as exceptional case. The call will need to catch the method and act accordingly.
- return multiple values, which can archive by declare custom type(class or struct) or valueTuples(int,string). which I think is not really fit what you are trying to do.
- try pattern. you can refer to it from .net own class library.(eg. Int.TryParse) . the caller need to check for a bool and act accordingly.
- change return type from int to int? . caller will need to check for null and display message accordingly.