shorthand If Statements: C# - c#

Just a quick one, Is there anyway to shorthand this?
It's basically determining the direction left or right, 1 for left, 0 for right
In C#:
if (column == 0) { direction = 0; }
else if (column == _gridSize - 1) { direction = 1; }
else { direction = rand.Next(2); }
The statement following this will be:
if (direction == 1)
{
// do something
}
else
{
// do something else
}
If there isn't, it doesn't really matter! just curious:)

To use shorthand to get the direction:
int direction = column == 0
? 0
: (column == _gridSize - 1 ? 1 : rand.Next(2));
To simplify the code entirely:
if (column == gridSize - 1 || rand.Next(2) == 1)
{
}
else
{
}

Use the ternary operator
direction == 1 ? dosomething () : dosomethingelse ();

Yes. Use the ternary operator.
condition ? true_expression : false_expression;

Recently, I really enjoy shorthand if else statements as a swtich case replacement. In my opinion, this is better in read and take less place. Just take a look:
var redirectUrl =
status == LoginStatusEnum.Success ? "/SecretPage"
: status == LoginStatusEnum.Failure ? "/LoginFailed"
: status == LoginStatusEnum.Sms ? "/2-StepSms"
: status == LoginStatusEnum.EmailNotConfirmed ? "/EmailNotConfirmed"
: "/404-Error";
instead of
string redirectUrl;
switch (status)
{
case LoginStatusEnum.Success:
redirectUrl = "/SecretPage";
break;
case LoginStatusEnum.Failure:
redirectUrl = "/LoginFailed";
break;
case LoginStatusEnum.Sms:
redirectUrl = "/2-StepSms";
break;
case LoginStatusEnum.EmailNotConfirmed:
redirectUrl = "/EmailNotConfirmed";
break;
default:
redirectUrl = "/404-Error";
break;
}

Related

IF, better approach

I'm have the
Table below and I want to count how many times a row value is greater than 2.
Please note the columns are linked, 1st column->3rd , 2nd->4th .
Sometimes I want to count if tms = "abc", and sometimes if they are opposite of abc.
Is there any different approach for this case?
var_case = 1;
var tms = "abc";
foreach (DataRow r in d.Rows)
{
gCount+= cases(r, _case, tms, true) ? 1 : 0;
// gCount+= cases(r, _case, tms) ? 1 : 0;
}
private bool cases(DataRow d, int _case, string tms = "", bool t = false)
{
var h = d.ItemArray[0].ToString();
bool res = false;
switch (_case)
{
case 1: res = (h == tms) ? ((!t) ? ((int)d.ItemArray[2] > 2) ? true : false : ((int)d.ItemArray[3] > 2) ? true : false) : ((!t) ? ((int)d.ItemArray[3] > 2) ? true : false: ((int)d.ItemArray[2] > 2) ? true : false); break;
default:
break;
}
return res;
}
You can use Linq to count the rows, making the rows counting more explicit.
var _case = 1;
var tms = "abc";
int gCount = table.Rows
.Cast<DataRow>()
.Count(r => cases(r, _case, tms, false));
In the condition, you can separate the retrieving of the column index and getting the data. It would make things less complicated.
private static bool cases(DataRow dataRow, int _case, string tms = "", bool invertedSearch = false)
{
switch (_case)
{
case 1:
string h = (string)dataRow.ItemArray[0];
int column = (h == tms) ^ invertedSearch ? 2 : 3;
return (int)dataRow.ItemArray[column] > 2;
default:
return false;
}
}

Convert Multiple if condition into Ternary Operator

I want to convert below condition to ternary
if (!string.IsNullOrEmpty(objModel.Status))
{
if (objModel.Status == "0")
{
Model.Sort = "Result1";
}
else if (objModel.Status == "8")
{
Model.Sort = "Result2";
}
else
{
Model.Sort = "Result3";
}
}
I have tried as below but it went upto if and else not else if
Model.Sort = !string.IsNullOrEmpty(Model.Status)
? (Model.Status == "0" ? Retult1 : string.Empty)
: string.Empty;
Keep a local variable for simplification
var x = objModel.Status;
if (string.IsNullOrEmpty(x))
{
Model.Sort = x=="0" ? "Result1" :
x=="8" ? "Result2" :
"Result3";
}
you can have ternary operator like this
a ? b : c ? d : e
to get this:
if (a) {
b
}
else if (c) {
{
d
}
else {
e
}
in your case
objModel.Status == "0" ? Model.Sort = "Result1" : objModel.Status == "8" ? Model.Sort = "Result2" : Model.Sort = "Result2";
I hope this helps.
You can write your code using ternary operators like this:
Model.Sort = string.IsNullOrEmpty(objModel.Status) // if (string.IsNullOrEmpty(Status))
? Model.Sort // Model.Sort = Model.Sort;
: objModel.Status == "0" // else if (Status == "0")
? "Result1" // Model.Sort = "Result1";
: objModel.Status == "8" // else if (Status == "8")
? "Result2" // Model.Sort = "Result2";
: "Result3"; // else Model.Sort = "Result3";
Where the first condition represents the if condition, and then each statement after a : operator that is a comparison represents an else if, and finally the result after the last : represents the final else assignment.
The first condition is kind of a "dummy" condition (because if it's true nothing really changes*), but is required if we want to include the IsNullOrEmpty check in the ternary operations, since the ternary operator has to return a value in both the true and false cases.
I'm not sure if the dummy assignment would get optimized away or if the setter is called in that "dummy" case. If the setter is called then potentially this could have a different effect than your original code, depending on what the setter code does.

c# OR operator, how to find out which option triggered

So if I use OR statement like this:
if (option1 == true || option2 == true)
{
Print("would like to print the option that triggered above");
}
How do I figure out which option out of these 2 has been triggered?
Thanks
You can do it using else if condition.
E.g.:
if(option1 && !option2)
{
//Option 1
}else if(!option1 && option2)
{
//option 2
}else if(option1 && option2)
{
//both
}
else
{
//no option
}
I'm sorry but you can't.
But instead you can split the if statement
if (option1 == true)
{
Print("option1 is true");
}
if (option2 == true)
{
Print("option2 is true");
}
or put additional checks inside of the if statement(but it's useless).
if(option1 == true || option2 == true){
if (option1 == true)
{
Print("option1 is true");
}
if (option2 == true)
{
Print("option2 is true");
}
}
also you can use
if(option1){}
instead of
if(option1 == true){}
oh, and you could also use this to check if both are true
if (option1 == true && option2 == true)
{
Print("both options are true");
}
if (option1 == true || option2 == true)
{
if(option1)
Print("Option 1");
else
Print("Option2");
}
You could possibly get in dangerous water, though, as you might end up with a situation where option1 == true and option2 == true.
If you really need to know which one was triggered, I would suggest you branch out. if(option1 == true) { ... } else if(option2 == true) { ... } else { ... }.
You could also do this:
if(option1 == true || option2 == true) {
if(option1 == true) {}
if(option2 == true) {}
}
You'd have to test them both again inside the if statement.
Note the short circuit 'or' statement you have used (||). So if option1 one is true, it wont test the second condition.
if (option1 == true || option2 == true)
{
if (option1 == true)
{
Print("option1");
}
else
{
Print("option2");
}
}
You can not find which statement is trigger in your code, you need 2 statements
if (option1 == true || option2 == true)// statement 1
{
Print( option1 ? "option 1 triggered above" : "option 2 triggered above");// statement 2
}

Compare two strings and check the changed value in a contain range

I have 6 properties:
oldprop1,oldprop2,oldprop3
newprop1,newprop2,newprop3
I am going to check if the value changed. If it changed in a certain combination of ways, then I want to log it.
If these 5 changes happen, then it should be logged:
P to Y
P to N
blank to Y -- here blank means ""
blank to N
N to Y
What I am doing now
if (!oldprop1.Trim().Equals(newprop1.Trim()) && (oldprop1.ContainsAny("P", "N","")) && newprop1.ContainsAny("Y", "N"))
{
//log me to DB
}
if (!oldprop2.Trim().Equals(newprop2.Trim()) && (oldprop2.ContainsAny("P", "N", "")) && newprop2.ContainsAny("Y", "N"))
{
//log me to DB
}
if (!oldprop3.Trim().Equals(newprop3.Trim()) && (oldprop3.ContainsAny("P", "N", "")) && newprop3.ContainsAny("Y", "N"))
{
//log me to DB
}
public static bool ContainsAny(this string haystack, params string[] needles)
{
foreach (string needle in needles)
{
if (haystack.Contains(needle))
return true;
}
return false;
}
Is there any better way to write this?
better to use switch statement .here is the code
public void CompareAndLog(string first, string second)
{
switch (first)
{
case "P": if (second == "Y" || second == "N") ;//log me to db
break;
case "N": if (second == "Y") ; //log me to db
break;
case "": if (second == "Y" || second == "N") ;//log me to db
break;
}
}
You can write a method where you pass in oldpropX and newpropX and do the logic in there, then you just do:
if (SomeFunc(oldprop1, newprop1) || SomeFunc(oldprop2, newprop2)...)
{
// log to DB.
}
SomeFunc() would do the Equals check and the P,N,etc. check.

Cleaning up multiple IF statements in the code

My code is like this
string statuscodeToSet;
if (xElementAltItem != null && (generalstatuscode.Contains(currentstatuscode) && xElementAltItem.Value.Trim() =="null"))
{
statuscodeToSet = "1";
}
if (xElementupdateDate != null && (xElementAltItem != null && (generalstatuscode.Contains(currentstatuscode) && xElementAltItem.Value.Trim() == "null") && xElementupdateDate.Value == "01-JAN-2099"))
{
statuscodeToSet = "2";
}
if (xElementupdateDate != null && (xElementAltItem != null && (generalstatuscode.Contains(currentstatuscode) && xElementAltItem.Value.Trim() == "null") && xElementupdateDate.Value != "01-JAN-2099"))
{
statuscodeToSet = "3";
}
if (xElementAltItem != null && (generalstatuscode.Contains(currentstatuscode) && xElementAltItem.Value.Trim() != "null"))
{
statuscodeToSet = "4";
}
if (xElementAltItem != null && (currentstatuscode == "Act-NotOrd" && xElementAltItem.Value.Trim() == "null"))
{
statuscodeToSet = "5";
}
Obviously I don't think this is the best way to code this.Is there any way I can shorten this code and looks it more standard. May be using Linq
This seems to be the simplest possible, but I don't think this is simple.
if (xElementAltItem != null)
{
if (xElementAltItem.Value.Trim() == "null")
{
if (generalstatuscode.Contains(currentstatuscode))
{
statuscodeToSet = "1";
if (xElementupdateDate != null)
{
if (xElementupdateDate.Value == "01-JAN-2099")
{
statuscodeToSet = "2";
}
if (xElementupdateDate.Value != "01-JAN-2099")
{
statuscodeToSet = "3";
}
}
}
if ((currentstatuscode == "Act-NotOrd"))
{
statuscodeToSet = "5";
}
}
else
{
if (generalstatuscode.Contains(currentstatuscode))
{
statuscodeToSet = "4";
}
}
}
You really need to tease out the logic here by creating some meaningful variable names to make the conditions read like English otherwise your code is vulnerable to bugs.
Update: I seem to have introduced a difference wrt the original in the handling of the update date as it appears I collapsed three states into two (whoops!) which appears in steps #2/#3. In any case, I believe the following is still an applicable template to follow.
Step #1: Eliminate the duplicate conditional checks with variables.
This simplifies the conditionals greatly and makes it easier to see what is "supposed" to happen.
var nullAlt = xElementAltItem != null ? xElementAltItem.Value.Trim() == "null" : false;
var hasCurrentStatus = generalstatuscode.Contains(currentstatuscode);
var updateDate = xElementupdateDate != null ? xElementupdateDate.Value : "";
if (nullAlt && hasCurrentStatus)
{
statuscodeToSet = "1";
}
if (nullAlt && hasCurrentStatus && updateDate == "01-JAN-2099"))
{
statuscodeToSet = "2";
}
if (nullAlt && hasCurrentStatus && updateDate != "01-JAN-2099"))
{
statuscodeToSet = "3";
}
if (!nullAlt && hasCurrentStatus)
{
statuscodeToSet = "4";
}
if (nullAlt && currentstatuscode == "Act-NotOrd")
{
statuscodeToSet = "5";
}
Step #2: Group the separate conditions and rewrite the code with "nested" and "else" conditionals.
This should eliminate most (if not all) of the duplicate checks and provide "one path" through the entire conditional structure. The order of grouping depends upon the logical importance of each condition and how well it eliminates duplicates between branches. In this case the code is grouped by nullAt and then hasCurrentState.
// ..
if (nullAlt) {
if (hasCurrentStatus) {
statuscodeToSet = "1";
if (updateDate == "01-JAN-2099"))
{
statuscodeToSet = "2";
} else { /* updateDate != "01-JAN-2099" */
{
statuscodeToSet = "3";
}
} else if (currentstatuscode == "Act-NotOrd")
{
statuscodeToSet = "5";
}
} else { /* !nullAlt */
if (hasCurrentStatus)
{
statuscodeToSet = "4";
}
}
Step #3: Place the code into a separate function and return the result.
That is, don't assign the "status" to a variable. Besides maintaining tidy code separation and self-documentation, this is useful because then invalid code paths/logic can be more easily spotted.
For instance, return "1" makes no sense where it is located (as then neither status "2" nor "3" could be reached and if it removed then status "1" is never returned!) and there are some "otherwise" cases not handled.
string GetStatusCode (..) {
// ..
if (nullAlt) {
if (hasCurrentStatus) {
// whoops! What was this doing??
return "1";
if (updateDate == "01-JAN-2099"))
{
return "2";
} else { /* updateDate != "01-JAN-2099" */
{
return "3";
}
} else if (currentstatuscode == "Act-NotOrd")
{
return "5";
} else {
// return what here?
}
} else { /* !nullAlt */
if (hasCurrentStatus)
{
return "4";
} else {
// return what here?
}
}
}
At this final stage, the usage of the intermediate variables could be reverted without losing much readability because the duplicate expressions have been eliminated. However, excepting in cases where lazy evaluation is strictly required, separate variables are perfectly valid - use them if they make the code cleaner.
Using enumerations or constants would also be an improvement: a status value of NeedsUpdate is more informative than "3".
I recommend keeping it simple and following the approach outlined above.
YMMV.
Try this:
if (xElementAltItem == null)
return;
statuscodeToSet = "1";
if (xElementAltItem.Value.Trim() == "null")
if (generalstatuscode.Contains(currentstatuscode))
statuscodeToSet = xElementupdateDate != null && xElementupdateDate.Value != "01-JAN-2099" ? "3" : "2";
statuscodeToSet = currentstatuscode == "Act-NotOrd" ? "5" : null;
else
statuscodeToSet = generalstatuscode.Contains(currentstatuscode) ? "4" : null;

Categories