Convert Multiple if condition into Ternary Operator - c#

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.

Related

Assigning function invocation to anonymous field in c#

I am returning anonymous type from my linq query:
select new {
Exists = true,
Code = new Func<string,string>((string param) => {
if (param == "T")
return "Tab";
if (param == "E")
return "Eub";
if (param == "C")
return "GTW";
if (param == "X")
return "XUX";
return "";
}
}
An error:
A lambda expression with a statement body cannot be converted to an expression tree
is being thrown but it does not tell me anything.
Question: How to handle that without creating new nonanonymous function?
Why use Func<string,string>?
something.Select(x => new {
Exists = true,
Code = x.param == "T" ? "Tab" :
x.param == "E" ? "Eub" :
x.param == "C" ? "GTW" :
x.param == "X" ? "XUX" : ""
});

Concat two strings and print it on a label c# wpf

I have several radioButtons stored in two different strings.
I need them printed bound together on a label. How can I do it?
private void Button_Click(object sender, RoutedEventArgs e)
{
String cad1 = null;
String cad2 = null;
if (rad1.IsChecked == true)
{
cad1 = "Ok";
}
else if (rad2.IsChecked == true)
{
cad1 = "Ok Cancel!";
}
else if (rad3.IsChecked == true)
{
cad1 = "Yes No";
}
else if (rad4.IsChecked == true)
{
cad1 = "Yes No Cancel";
}
else if (rad5.IsChecked == true)
{
cad1 = "Retry Cancel";
}
else if (rad6.IsChecked == true)
{
cad1 = "Abort Retry Cancel";
}
else if (rad7.IsChecked == true)
{
cad2 = "Information";
}
else if (rad8.IsChecked == true)
{
cad2 = "Exclamation";
}
else if (rad9.IsChecked == true)
{
cad2 = "Question";
}
else if (rad10.IsChecked == true)
{
cad2 = "Error";
}
I need to print the result of these two strings, but for the moment, the second string is not printed
cad1 = cad1 + cad2;
lab2.Content = cad1;
}
}
The reason is all of your cad2 variables are contained in else if statements.
Modify the line
else if (rad7.IsChecked == true)
to be
if (rad7.IsChecked == true)
EDIT
I would also recommend removing all == true, they are unnecessary.
If the cad1 and cad2 aren't being used after this event I'd recommend creating a single string variable and appending the values that would have been cad1 and cad2 to it.
var cont = "";
if (rad1.IsChecked) cont += "Ok";
...
if (rad7.IsChecked) cad2 += "Information";
...
lab2.Content = cont;
Elsif only get s evaluated if the first if was not true, so if cad1 gets a value, cad2 never gets a value.
Furthermore, if (rad9.IsChecked == true) is exacttly the same as `if (rad9.IsChecked)'
And finally, if you're using an up-to-date version of C# you can use the ternaty operator:
var cad1 = rad1.IsChecked
? "Ok"
: rad2.IsChecked
? "Ok Cancel!"
: rad3.IsChecked
? "Yes No"
: rad4.IsChecked
? "Yes No Cancel"
: rad5.IsChecked
? "Retry Cancel"
: rad6.IsChecked
? "Abort Retry Cancel"
: null;
var cad2 = rad7.IsChecked
? "Information"
: rad8.IsChecked
? "Exclamation"
: rad9.IsChecked
? "Question"
: rad10.IsChecked
? "Error"
: null;
Or, if you like it more concise:
var cad1 = rad1.IsChecked ? "Ok"
: rad2.IsChecked ? "Ok Cancel!"
: rad3.IsChecked ? "Yes No"
: rad4.IsChecked ? "Yes No Cancel"
: rad5.IsChecked ? "Retry Cancel"
: rad6.IsChecked ? "Abort Retry Cancel"
: null;
var cad2 = rad7.IsChecked ? "Information"
: rad8.IsChecked ? "Exclamation"
: rad9.IsChecked ? "Question"
: rad10.IsChecked? "Error"
: null;
Now, I wonder if rad1-10 are radiobuttons, and why I cannot see in the name which ones belong to the same group. I hope 1-6 are in one and 7-10 are in another group, but better naming would avoid confusion and possible mistakes...
In your if-else chain you never set values for both cad1 and cad2 so you never get the correct output.
Te easieset way to get what you want is to split the chain to look llike this
...
else if (rad6.IsChecked == true)
{
cad1 = "Abort Retry Cancel";
}
if (rad7.IsChecked == true)
{
cad2 = "Information";
}
...

Need help in reducing the Cyclomatic complexity of LINQ query used for constructing JSON string

I have got 5 different sources of data(request, lsitCC, listSEDI, listSEDIFees and XMLRoot loaded into respective C# Array list objects). I need to construct a JSON request by combining the data from all of those sources based on certain conditions. I have written below code in C# using NewtonSoft.JSON. The cyclomatic complexity for this LINQ query is coming around 40 which is at a higher side. Could anyone please advice on how the complexity can be reduced. Thanks in advance.
I presume the query is pretty user readable, Please let me know if inline comments are required.
var input = from RequestNode in request
select new
{
Documents = (from objCC in lsitCC
where objCC.ID == RequestNode.ID
select new
{
Request = (from objSEDI in listSEDI
where objSEDI.ID == objCC.ID && RequestNode.POSTAL.Count(p => p.PID == objSEDI.PID) > 0
join Config in RequestNode.POSTAL on objSEDI.PID equals Config.PID
select new
{
ReqItem = (Config.ReqItem == null) ? "" : Config.ReqItem,
Code = (RequestNode.Code == null) ? "" : RequestNode.Code,
Camp = (RequestNode.Camp == null) ? "" : RequestNode.Camp,
CCT = new
{
ID = (objCC.ID == null) ? "" : objCC.ID,
Band = (RequestNode.Band == null) ? "" : RequestNode.Band,
Context = (RequestNode.Context == null) ? 0 : RequestNode.Context,
IsActive = (RequestNode.IsActive == null) ? false : RequestNode.IsActive,
MaxLimit = (objCC.MaxLimit == null) ? 0 : objCC.MaxLimit,
MinLimit = (objCC.MinLimit == null) ? 0 : objCC.MinLimit
},
User = RequestNode.User,
POSTAL = new
{
PID = (objSEDI.PID == null) ? "" : objSEDI.PID,
Type = (Config.Type == null) ? "" : Config.Type,
Amount = (Config.Amount == null) ? 0 : Config.Amount,
IsValid = (Config.IsValid == null) ? false : Config.IsValid,
Code = (Config.Code == null) ? "" : Config.Code,
Infos = new
{
Info = (from objRoot in XMLRoot
where objRoot.ID == objCC.ID && objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1" && objRoot.Code == Config.Type.Substring(0, 3) && objRoot.PIDCode == Config.Type.Substring(3, 1)
select new
{
InfoFrom = (objRoot.InfoFrom == null) ? "" : objRoot.InfoFrom,
Selection = (objRoot.Handling == null) ? "" : objRoot.Selection,
Rate = (objRoot.Rate == null) ? "" : objRoot.Rate
})
},
POSTALFee = from objSEDIFee in listSEDIFees
where objSEDIFee.ID == objCC.ID && objSEDIFee.PID == objSEDI.PID
select new
{
BaseValue = (objSEDIFee.BaseValue == null) ? 0 : objSEDIFee.BaseValue,
UpdatedValue = (objSEDIFee.UpdatedValue == null) ? 0 : objSEDIFee.UpdatedValue,
BaseType = (objSEDIFee.BaseType == null) ? "" : objSEDIFee.BaseType,
UpdatedType = (objSEDIFee.UpdatedType == null) ? 0 : objSEDIFee.UpdatedType
},
OutputRoot = new
{
Output = from output in outputroot
select new
{
Type = 0,
SubType = 0,
OutputReference = 0
}
}
},
})
})
};
var streamRead = JsonConvert.SerializeObject(input, Newtonsoft.Json.Formatting.Indented);
This seems like simply a case of adding the appropriate amount of translators to your code base. Yes Translators are tedious, but if you feel you have too much logic in one query here, I suggest that could be the way for you to go.
This will mean that you will have to either ditch the anon types, or embrace the dynamic keyword (would that even work?!)
You may also need to look at some sort of build pattern or intermediate state.
On further inspection, it appears that you introduce some global variable halfway down the query e.g. XMLRoot & listSEDIFees. It might be nicer if this was more explicit. You could also cut down on excessive work by pre filtering XMLRoot with the static part of your where clause (objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1") instead of re-running that each time. Maybe something like
var channel1Group1Info = XMLRoot.Where(objRoot=>objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1").ToArray();
The rest I would just pick off one piece at a time, reducing the amount of work this query is doing.

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;

shorthand If Statements: 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;
}

Categories