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
Related
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;
}
}
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;
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.
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
}
I have the following line of code:
public bool dcpl_radar()
{
if (radar == null)
return false;
else
{
if (radar != null)
{
if (radar.InvokeRequired)
radar.BeginInvoke(new MethodInvoker(delegate()
{
radar.Visible = false;
}));
else
this.radar.Visible = false;
radar = null;
}
return true;
}//end of else statement
}
but VStudio keeps throwing an error on the invoke line. I've checked the Debugger and if (radar == null) is true, yet VStudio is trying to evaluate a part of the code it shouldn't be in. Can someone explain why it's doing this please?
Wait a minute... I think we have a race condition.
Lets say you BeginInvoke, almost immediately you set radar = null.
There really is no telling when your anonymous delegate will be executed.
I would imagine this should solve your issue.
public bool dcpl_radar()
{
if (radar != null)
{
if (radar.InvokeRequired)
{
radar.BeginInvoke(new MethodInvoker(HideRadar));
}
else
{
HideRadar();
}
return true;
}
return false;
}
private void HideRadar()
{
this.radar.Visible = false;
this.radar = null;
}
What is happening:
The anonymous delegate is being called after you set the radar to null.
How to fix it
public bool dcpl_radar()
{
if (radar == null)
return false;
else
{
if (radar != null)
{
if (radar.InvokeRequired)
radar.BeginInvoke(new MethodInvoker(delegate()
{
radar.Visible = false;
radar = null;
}));
else {
this.radar.Visible = false;
radar = null;
}
}
return true;
}//end of else statement
}
(Note where I've moved your 'null' assignments).
Though I am a bit worried about the point of setting a variable to null, it's generally a sign of a bad design.