C# nested if-else optimization with almost similar values - c#

I have new user data (i want to import/update it). Accounts is finded by user data.
I want to update or create new accounts depended on finded accounts by user data
:
if (accountById != null)
{
if (accountByNumber != null)
{
if (accountById.Id == accountByNumber.Id)
{
if (_isSpecialData)
{
AddUserDataToAccount(userData, accountByNumber);
if (userData.Status == Blocked) return;
}
}
else
{
_log.Error($"Bad");
return;
}
}
else
{
AddUserDataToAccount(userData, accountById);
}
}
else
{
if (accountByNumber != null)
{
if (accountByNumber.RefNo == null)
{
SetAccountAdditionalId(accountByNumber, userData.AdditionalId);
if (_isSpecialData)
{
AddUserDataToAccount(userData, accountByNumber);
if (userData.Status == Blocked) return;
}
}
else
{
_log.Error($"Bad");
return;
}
}
else
{
CreateCardAndProfile2(userData, out createdNewAccount);
CreateNewAccount(userData, out createdNewAccount);
}
}
UpdateAccountData(userData, createdNewAccount);
The above method works, but I would like to know if there is any way to make it more readable, optimized?

You can use the switch operator so you can remove a lot of the if statements. if works like this:
(Note: Make sure you have a default case and a break; at the end of every case)
switch(%a%variable%here%) {
case %variable%value& {
%code%here%;
break;
}
}

Related

else { if {} } and else if {}

Is there any difference between:
else
{
if {}
}
and
else if {}
For example,
var statusValue = "Error";
if (!canWrite)
{
statusValue = "NotOwner";
}
else
{
if (syncJob.Status == "Idle")
{
statusValue = "InProgress";
}
}
and
var statusValue = "Error";
if (!canWrite)
{
statusValue = "NotOwner";
}
else if (syncJob.Status == "Idle")
{
statusValue = "InProgress";
}
Do the above both codes work in the same way?
The two versions of code you showed us do the same thing as each other, but they are not syntactically the same.
When you use the else if language element, you can cascade the clauses, something like this:
if (a == 1) {
// some code
} else if (b == 2) {
// some other code
} else if (c == 3) {
// even more code
} else {
// still more
}
Only one of the compound ( code surrounded by { } ) statements inside that example gets executed, guaranteed.
When you nest if within else, you don't get exactly the same thing. And if you write it that way when you want else if you'll make your code much harder to read. It's a good way to make your future self hate your present self when you must change or debug your code.
Consider
if (condition1)
DoA();
else
DoB();
Is exactly equivalent to
if (condition1)
{
DoA();
}
else
{
DoB();
}
I strongly recommend the latter because you are less likely to slip errors into your code doing maintenance when the brackets are there.
So...
if (condition1)
DoA();
else if (condition2)
DoB();
else
DoC();
Is going to be the same as a version with brackets.
As long as you restrict yourself to single statements, you don't need brackets. The brackets demarcate blocks of statements, and both if and else can work equally well with either statements or blocks.
One thing that shakes out of all this is that
if (condition1)
DoA();
else
{
if (condition2)
DoB();
}
else
DoC();
And
if (condition1)
DoA();
else
{
if (condition2)
{
DoB();
}
}
else
DoC();
Are exactly equivalent to the previous bracket-free example
if (!canWrite)
{
statusValue = "NotOwner";
}
// else is ran if the above is false and the condition is true
else if (syncJob.Status == "Idle")
{
statusValue = "InProgress";
}
if (!canWrite)
{
statusValue = "NotOwner";
}
// Runs if the above is false
else
{
// Runs any code up to this point no matter the code condition below
// Runs if the first is false and this is true
if (syncJob.Status == "Idle")
{
statusValue = "InProgress";
}
// Runs any code up to this point no matter the code condition above
}
Syntax wise no, but when it is recompiled you will end up with different code... more jumps

Refactoring code to use less if statements

I was just wondering what would be the best approach to refactoring this statement to use less of the condidtions? Im reallt strucggling to clean this statement up without having the same functionality if somone could point me in the right direction i would be very gratefull
try
{
var errorProviders = new List<ErrorProvider>() { epEmail, epAlternative, epMobile, epTown, epLandline, epHouseName, epForeName, epSurname, epPostcode, epCountry, epHouseName, epLocality, epCounty };
foreach (Control c in panel1.Controls)
{
if (c is SpellBox || c is TextBox)
{
if (!string.IsNullOrWhiteSpace(txt_ForeName.Text) | !string.IsNullOrWhiteSpace(txt_SurName.Text))
{
if (cmb_Title.SelectedIndex != -1)
{
if (cmb_PrefConTime.SelectedIndex != -1)
{
if (isPhoneNumber())
{
if (errorProviders.Any(e => e.GetError(c).Length > 0))
{
return false;
}
}
else
{
epPrefConNumber.SetError(cmb_PrefConNumber, "Error");
return false;
}
}
else
{
epPrefConTime.SetError(cmb_PrefConTime, "Error in: prefered contact time feild");
return false;
}
}
else
{
epTitle.SetError(cmb_Title, "Title");
return false;
}
}
else
{
epBothNames.SetError(txt_SurName, "Error:");
epBothNames.SetError(txt_ForeName, "Error:");
return false;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString())+ "Error has occurred, Please cancel and try again!");
}
return true;
If there is a way to use bare minumum conditions to reduce code ?
If you have to check all those conditions then you have to check all those conditions. Your most egregious issues, in my opinion, are the deep nesting and validating fields that are completely unrelated to the control inside your loop. You can fix the nesting by reversing your if conditions and returning early. For the rest, just move the unrelated validation outside the loop.
try
{
var errorProviders = new List<ErrorProvider>() { epEmail, epAlternative, epMobile, epTown, epLandline, epHouseName, epForeName, epSurname, epPostcode, epCountry, epHouseName, epLocality, epCounty };
if (string.IsNullOrWhiteSpace(txt_ForeName.Text) && string.IsNullOrWhiteSpace(txt_SurName.Text))
{
epBothNames.SetError(txt_SurName, "Error:");
epBothNames.SetError(txt_ForeName, "Error:");
return false;
}
if (cmb_Title.SelectedIndex == -1)
{
epTitle.SetError(cmb_Title, "Title");
return false;
}
if (cmb_PrefConTime.SelectedIndex == -1)
{
epPrefConTime.SetError(cmb_PrefConTime, "Error in: prefered contact time feild");
return false;
}
if (!isPhoneNumber())
{
epPrefConNumber.SetError(cmb_PrefConNumber, "Error");
return false;
}
foreach (Control c in panel1.Controls.Where(x => x is SpellBox || x is TextBox))
{
if (!errorProviders.Any(e => e.GetError(c).Length > 0))
{
return false;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString())+ "Error has occurred, Please cancel and try again!");
}
return true;

Why my C# code is causing a Stack Overflow

This is the code giving a stack overflow it only happens about half the time and i have no idea why it's doing it. From what I seen it only happens with the Coms(TopCom, etc) are in a mass of numbers so around 5+ then it stack overflows.
public bool getConnected(int d) {
if (topCom.connection != null) {
if (d != topCom.connection.id) {
if (topCom.connection.id == 0) {
return true;
} else if (topCom.connection.connected == true) {
if (Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id)) {
return true;
}
}
}
}
if (leftCom.connection != null) {
if (d != leftCom.connection.id) {
if (leftCom.connection.id == 0) {
return true;
} else if (leftCom.connection.connected == true) {
if (Development.instance.currentDos.buttons[leftCom.connection.id].getConnected(id)) {
return true;
}
}
}
}
if (rightCom.connection != null) {
if (d != rightCom.connection.id) {
if (rightCom.connection.id == 0) {
return true;
} else if (rightCom.connection.connected == true) {
if (Development.instance.currentDos.buttons[rightCom.connection.id].getConnected(id)) {
return true;
}
}
}
}
if (botCom.connection != null) {
if (d != botCom.connection.id) {
if (botCom.connection.id == 0) {
return true;
} else if (botCom.connection.connected == true) {
if (Development.instance.currentDos.buttons[botCom.connection.id].getConnected(id)) {
return true;
}
}
}
}
return false;
}
This happens in recursive functions where you don't have a base condition for ending the recursion. You basically keep calling the function until you reach stack overflow.. Trace your code through and figure out why it calls itself endlessly.
The fact that people here can't really tell what you're trying to accomplish is a code smell of sorts.
A big part of that is the fact that you have an incredible amount of nesting in your code. Nested conditionals increase the difficulty of debugging code, as you're discovering now. Additionally, you could easily combine some of your conditionals - all of your conditionals in any top-level branch can actually be combined into one statement, as follows:
if ((topCom.connection != null && d != topCom.connection.id && topCom.connection.id == 0) ||
(topCom.connection.connected == true &&
Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id)))
{
return true;
}
return false;
As far as I can imagine, there's no point in having separate conditional branches that perform the same function, e.g. if (a) { return true; } else if (b) { return true; }. Just move the logic from else if into the original if conditional.
However, I'd recommend encapsulating some or all of this logic into a separate function, given that it seems like you're performing the same logic on each of your connections. You could create a function like so:
public bool ConnectionIsValid(connectionObject // replace with the actual type)
{
if (topCom.connection != null && d != topCom.connection.id && topCom.connection.id == 0)
|| (topCom.connection.connected == true
&& Development.instance.currentDos.buttons[topCom.connection.id].getConnected(id))
return true;
return false;
}
So that you could then just call ConnectionIsValid on each of your connections, rather than using 80-some lines on conditionals for each connection.
It also seems doubtful that there's a StackOverflowException occurring in this code. Unless you have a circular reference related to any of the objects referenced in this code (in which case, there's a decent chance you used a setter accessor to assign a value to the same variable:
object A
{
set
{
this.A = value;
}
}
which will always cause a stack overflow, it's likely you've introduced some sort of recursion outside the scope of the included code.

How to choose between different if conditions depending on another variable

I've been thinking about this problem for some time, but i just can't think of a solution without having to write duplicate code. The problem in part c# and part pseudo-code:
bool test = true;
if (test == true)
{
if(first condition) {code}
}
else
{
if(different condition) {same code as above)
}
I have to use this part in a performance intensive part of my program and i'd have to transfer 3 big parameters, which is why i'd rather not use a method.
Is there another way to solve this?
if((test && firstCondition) || (!test && differentCondition)) {
//code
}
if ((test && first_condition) || (!test && different_condition)) {
callSomeFunction();
}
I'd do it like this:
// create an inline function to capture the
Action workAction = () => { //work; }
bool test = true;
if (test == true)
{
if(first condition) {workAction(); }
}
else
{
if(different condition) {workAction(); )
}
Depending on the complexity of the conditions, this approach can sometimes help:
bool doBigCall = false;
if (test1)
{
if (test2)
{
doBigCall = true;
}
else
{
// ...
}
}
else
{
// ...
}
if (doBigCall)
{
// write the big bit of code just once
}

Need help to refactor the nested if else statements

Please find the following code and help me write a better if...else code. I feel this is a very below average way to write else if.
{
Retrieve the number in focus.
string number= getnumber();
string zipcode;
int corporate;
bool bCoverageInBet = false;
try
{
//Get the address and zipcode of the number
GetAddress(number, out address);
if (adress!= null)
{
zipcode = adress.zipcode
//if the following are null means this is first time call
if (!(string.IsNullOrEmpty(_loadedZipcode)) && _address != null)
{
if (zipcode.Equals(_loadedZipcode))
{
if (adress.Equals(_address ))
{
if (focusChanged)
{
return result;
}
}
else
{
if (bCoverageInBet)
{
// case 2: Different address and different coverage which is in between, make a call anf get new valus for result
//return the new result
}
else
{
return //current result value;
}
}
}
}
else
{
_loadedZipcode = zipcode;
_address = adress;
GetResponse( out resp)
{
if ((resp != null))
{
bool isCorporate = false;
corporate = getValues();
if (corporate .Equals(100))
{
result = true;
return result;
}
else if (corporate > 0 && corporate < 100)
{
//Make a call to get corporate
bCoverageInBet = true;
LocationResponse objResults;
if (GetAddressbycorporate(out objResults, out errMsg))
{
if (objResults != null)
{
isCorporate = objResults.located;
if (isCorporate )
{
result = true;
}
}
}
}
return result;
}
return result;
}
else
{
DisplayError("No response ");
return result;
}
}
}
else
{
//To do: What is address comes null
}
}
catch (System.Exception ex)
{
//some ccode
}
return result;
}
Thanks
K
Refactor the method into smaller units as appropriate. Also, return early from the method rather than using else clauses.
E.g. instead of
if (adress!= null)
{
zipcode = adress.zipcode
//if the following are null means this is first time call
if (!(string.IsNullOrEmpty(_loadedZipcode)) && _address != null)
{
}
else
{
return false;
}
}
else
{
return false;
}
Do:
if (adress == null)
{
return false;
}
if (string.IsNullOrEmpty(_loadedZipcode) || _address == null)
{
return false;
}
There are quite a few other problems, but that should make the code cleaner to start with.
I don't think anyone is going to "help" you rewrite this code. However, I can offer some suggestions.
I have found it easier to trace my way down to the inner most if and try to rewrite and work my way backwards (up the chain). Depending on the IF block, it is sometimes easier to break them out into separate methods where appropriate.
Also, don't forget about the conditional operator. It can sometimes be clearer to use that than a whole if else block.
For example, property = (boolean expression) ? (true value) : (false value);
Here is a link to MSDN on it: conditonal operator documentation

Categories