ternary conditional operator If Else C# - c#

i wrote this code:
if (B_21_GDV_Variant.RowCount > 0)
{
metroContextMenuStrip1.Enabled = true;
B_21_GDV_Variant.AllowDeleting = false;
B_21_GDV_Variant.Columns["HB"].Format = "{0:N}";
B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment = HorizontalAlignment.Left;
}
else
{
metroContextMenuStrip1.Enabled = false;
B_21_GDV_Variant.AllowDeleting = true;
}
I just want to know, how to write it using ternary conditional operator ?

In general, it may not be recommended in this context, but it's still possible. Not only ternary conditional operator, but also using direct boolean values to set. This is:
metroContextMenuStrip1.Enabled = (B_21_GDV_Variant.RowCount > 0);
B_21_GDV_Variant.AllowDeleting = !(B_21_GDV_Variant.RowCount > 0);
B_21_GDV_Variant.Columns["HB"].Format = (B_21_GDV_Variant.RowCount > 0) ? "{0:N}" : B_21_GDV_Variant.Columns["HB"].Format;
B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment = (B_21_GDV_Variant.RowCount > 0) ? HorizontalAlignment.Left : B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment;
I would not recommend using the ternary conditional operator in this case since it does not help with readability and in general using it in this case will not generate any performance improvement.

If you wanted to force the use of ternary and you wanted some semblance of readability, then I'd suggest this:
var data =
B_21_GDV_Variant.RowCount > 0
? (
Enabled: true,
AllowDeleting: false,
Format: "{0:N}",
HorizontalAlignment: HorizontalAlignment.Left
)
: (
Enabled: false,
AllowDeleting: true,
Format: B_21_GDV_Variant.Columns["HB"].Format,
HorizontalAlignment: B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment
);
metroContextMenuStrip1.Enabled = data.Enabled;
B_21_GDV_Variant.AllowDeleting = data.AllowDeleting;
B_21_GDV_Variant.Columns["HB"].Format = data.Format;
B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment = data.HorizontalAlignment;

The closest form would be this:
_ = (B_21_GDV_Variant.RowCount > 0)
? new Func<bool>(() =>
{
metroContextMenuStrip1.Enabled = true;
B_21_GDV_Variant.AllowDeleting = false;
B_21_GDV_Variant.Columns["HB"].Format = "{0:N}";
B_21_GDV_Variant.Columns["HB"].CellStyle.HorizontalAlignment = HorizontalAlignment.Left;
return true;
})()
: new Func<bool>(() =>
{
metroContextMenuStrip1.Enabled = false;
B_21_GDV_Variant.AllowDeleting = true;
return false;
})();
That is, the ternary operator must return a value, which is here discarded (see the underscore).
The solution to wrap more operations is to enclose them in a delegate (Func in this case), then immediately executed (see the parens pair at the very end of each block).
Technically feasible, but I honestly don't see any convenience in doing that.

Related

Evaluating boolean expression in C#

I have written the code below to evaluate a boolean expression. The expression is coded in the form of objects.
It's one of those moments when I look at the code and think: I'm sure there's a better way to code that, using less boolean variables but can't see the right way to go. Any help? Unit tests have been written and are passing for a variety of inputs.
if (tree == null || !tree.IsActive || tree.FilterNodes == null)
{
return false;
}
var result = false;
foreach (var filter in tree.FilterNodes.Where(a => a.IsActive && a.ConditionNodes != null))
{
var tempBool = false;
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
else
{
tempBool = false;
}
}
else if (!string.IsNullOrWhiteSpace(condition.FieldName) && filter.LogicalOperator == LogicalOperator.And)
{
tempBool = false;
}
}
result = tempBool;
if (!result)
{
break;
}
}
return result;
You could set tempBool = false first thing in the loop and leave out the else and last else if:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
if (filter.LogicalOperator == LogicalOperator.Or && ApplyCondition(condition.ConditionOperator, value, condition.FieldValue))
{
tempBool = true;
break;
}
else if (filter.LogicalOperator == LogicalOperator.And)
{
tempBool = ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if (!tempBool)
{
break;
}
}
}
}
EDIT
It gets even simpler:
foreach (var condition in filter.ConditionNodes.Where(a => a.IsActive))
{
tempBool = false;
if (!string.IsNullOrWhiteSpace(condition.FieldName) && values.ContainsKey(condition.FieldName))
{
var value = values[condition.FieldName];
tempBool == ApplyCondition(condition.ConditionOperator, value, condition.FieldValue);
if ((filter.LogicalOperator == LogicalOperator.And && !tempBool) || (filter.LogicalOperator == LogicalOperator.Or && tempBool))
{
break;
}
}
}
In the if you need ApplyCondition to be true and then set tempBool to true (also the result of ApplyCondition). In the else if you set tempBoolto the result of ApplyCondition. That means you can set tempBoolto the result of ApplyConditionin the first place. Now you just need to decide if you need to break.
Taking a more o-o approach, I think your operators need to be defined by classes that inherit from a base class. The base class would have an abstract Evaluate method that your operators implement. You can then use o-o polymorphism to evaluate your operators without worrying about the internal details. Effectively you have the beginnings of a simple interpreter.
A more formal way to code a boolean interpreter is considering a boolean expression as generated by a formal grammar and writing a parser and an interpreter for it. The interpreter could be implemented as an abstract syntax tree.
I made an open source library to achieve this, if you want you can take a look on GitHub.

possible mistaken empty statement

I am new to programming and I have come across an issue called a "Possible mistaken empty statement" now I have done a lot of research on this topic, and the solution I was given was to remove the semi colon after the if statement, however this only produces more warnings and more errors that I currently do not know the solution to, I would very much appreciate the help, the language I am using is C#.
if (checkBox5.Checked = true) ;
Double value5 = Convert.ToDouble(checkBox4.Checked);
value5 = +1;
Double result5 = value5;
label2.Text = Convert.ToString(result5);
I guess that this is what you want:
if (checkBox5.Checked == true)
{
double value5 = Convert.ToDouble(checkBox4.Checked) + 1;
label2.Text = value5.ToString();
}
= is assigment, whereas == is checking for equality, on the other hand semicolon after if will terminate whole if statement.
Note that when you are checking for true then you can use this:
if (checkBox5.Checked) { }
You should use;
if (checkBox5.Checked == true)
not
if (checkBox5.Checked = true)
= is assignment operator, == is equality operator.
Check out;
http://msdn.microsoft.com/en-us/library/sbkb459w(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/53k8ybth(v=vs.110).aspx
And or course when you check your true value, you can use your if condition like;
if (checkBox5.Checked)
{
// Do something if checkBox5 is checked.
}
And if you use semicolon after your if condition;
if (checkBox5.Checked = true) ;
is equivalent to
if (checkBox5.Checked = true) { }
So in your case I think you shouldn't use semicolon either. Because if you use it, your code will be look like;
if (checkBox5.Checked = true)
{
}
Double value5 = Convert.ToDouble(checkBox4.Checked);
value5 = +1;
Double result5 = value5;
label2.Text = Convert.ToString(result5);
which I assume you don't want to do this. And remember, even if there is no body to execute, doesn't mean that the loop terminates.
The problem is the semi-colon at the end of your if as well as the single '=', should be:
if (checkBox5.Checked = true) ;
Should be:
if (checkBox5.Checked == true) // double '==' for equality comparison
if (checkBox5.Checked == true) ; // or you can use if (checkBox5.Checked)
// ^------------------- `=` assignment operator must be `==` equals
{ // missed
Double value5 = Convert.ToDouble(checkBox4.Checked);
value5 = +1;
// ^_______________ I assume you need `=+` addition assignment operator instead
// assigning `+1` to `value5 `
Double result5 = value5;
label2.Text = Convert.ToString(result5);
} /// missed
In addition to #des and #Soner answers, why don't you just do this :
if (checkBox5.Checked)
label2.Text = Convert.ToDouble(checkBox5.Checked).ToString();
I'm assuming you don't intend to increment value5 by 1 as it should be value5 += 1;

Is it better to do evaluation of bool once with more code or multiple times with less code

Is it better to evaluate bool once but have more code like this
if (klient.Podmioty.PodmiotRodzaj == "Osoba") {
textImie.Enabled = true;
textNazwisko.Enabled = true;
textNazwa.Enabled = false;
} else {
textImie.Enabled = false;
textNazwisko.Enabled = false;
textNazwa.Enabled = true;
}
comparing to this
textImie.Enabled = klient.Podmioty.PodmiotRodzaj == "Osoba";
textNazwisko.Enabled = klient.Podmioty.PodmiotRodzaj == "Osoba";
textNazwa.Enabled = klient.Podmioty.PodmiotRodzaj != "Osoba";
It's a generic question and maybe this little example is micro optimization but I would like to know whether reusing same bool over and over is not considered bad code.
Probably useful note is that klient.Podmioty.PodmiotRodzaj is actually variable from SQL brought by Entity Framework.
Evaluate once and use the results:
var conditionValue = (klient.Podmioty.PodmiotRodzaj == "Osoba");
textImie.Enabled = conditionValue;
textNazwisko.Enabled = conditionValue;
textNazwa.Enabled = !conditionValue;
The first option, less calculation time and no replica of code...
or, option C:
bool value = klient.Podmioty.PodmiotRodzaj == "Osoba";
textImie.Enabled = value;
textNazwisko.Enabled = value;
textNazwa.Enabled = !value;
but definitely not your option B.
The first is the common answer, and the second is hard to read. However, since you're only setting bools to the same as the condition, there's a third option:
bool t = (klient.podmioty.PodmiotRodzaj == "Osaba");
TextImed.Enabled = t;
TextNazwisko.Enabled = t;
TextNazwa.Enabled = !t;
(On phone, so I prob got the variable names wrong) This is debatibly slightly less clear than the first option, but brief (and avoids code forks).

if string item is not in string array

I have a string array.
I need to display buttons based on if the selected item is in the array.
I need to know how to tell the program if "(array.NOT Contains("string"))".
Please can anybody help me??
Thanks in advance
My code:
List<string> activationids = new List<string>();
foreach (ModuleActivation moduleactivation in activationid)
activationids.Add(moduleactivation.ActivationID);
string gvselectActID = GridView1.SelectedRow.Cells[1].Text;
if (activationids.Contains(gvselectActID))
{
activateInsert.Visible = true;
activateUpdate.Visible = false;
deactivate.Visible = true;
}
else if (activationids."NOT" Contains(gvselectActID))
{
activateInsert.Visible = false;
activateUpdate.Visible = true;
deactivate.Visible = false;
}
else
{
activateInsert.Visible = false;
activateUpdate.Visible = false;
deactivate.Visible = false;
}
}
Change:
else if (activationids."NOT" Contains(gvselectActID))
to
else if (!activationids.Contains(gvselectActID))
Or even simpler
bool containsItem=activationids.Contains(gvselectActID);
activateInsert.Visible = containsItem;
activateUpdate.Visible = !containsItem;
deactivate.Visible = containsItem;
The ! means "NOT". So you have to place it in front of the expression you need to negate;
!activationids.Contains("blahblah");
However, it's quite clear that if activationids.Contains("blahblah") is false, you are gonna go into the second case. Also, currently, your third block (... else { ...) will never be hit.
There are two very straightforward ways to do this:
Not the result of the bool function call:
if(!activationids.Contains(gvselectActID))
Check the result and compare it to false
if(activationids.Contains(gvselectActID) == false)
However, you are checking if it contains it in the first if() clause, which means that the first else clause will be fired if it isn't contained. There is no need to check, and there is no way that the third else will ever be fired.
Contains returns true or false, sou you cannot have three branches, you can do just
if (activationids.Contains(gvselectActID)) // it does contain
...
else // it does not contain
...
there are no other possibilities
[joke]
well it could work in this case
http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
[/joke]
This will be enough:
if (activationids.Contains(gvselectActID))
{
// Goes here if condition is true
activateInsert.Visible = true;
activateUpdate.Visible = false;
deactivate.Visible = true;
}
else
{
// Goes here if condition is false
activateInsert.Visible = false;
activateUpdate.Visible = true;
deactivate.Visible = false;
}
There are no other possible options - there can't be a third branch.
This makes no sense:
if(booleanCondition)
{}
else if (!booleanCondition)
{}
else
{}
As by definition, if the booleanCondition is false, the else branch will be taken - there is no need to test for it being false.

Error when assigning a boolean value

I am getting an error while assigning a value.
My code is:
protected bool ValidateProfile()
{
bool blnFirstName = false;
bool blnLastName = false;
bool blnEMail = false;
//(error on line below: "The left-hand side of an assignment must be a variable, property or indexer")
ValidateProfile() = false;
if txtFName != ""
blnFName = true;
if txtLName != ""
blnLName = true;
if txtEMail != ""
blnEMail = true;
if (blnFName) && (blnLName) && (blnEMail))
ValidateProfile = true;
}
How do I assign a boolean value to ValidateProfile ?
Thanks
You want
return false;
In C#, we don't assign values to the function name in order to return a value.
If you want to set the return value at a different point in time from when you return from the method, then you should do something like this:
bool retVal; // Defaults to false
if (condition)
retVal = true;
if (otherCondition)
retVal = false;
if (thirdCondition)
retVal = true;
return retVal;
You can't assign a value to a function. You need return false;
As others have pointed out, in C# you use return instead of MyFunction = x. In this scenario, you can assign the result of your final check to a boolean and return it:
bool retVal = (blnFName) && (blnLName) && (blnEMail);
return retVal;
Alternatively, you could just skip the assignment altogether:
return (blnFName) && (blnLName) && (blnEMail);
EDIT: I noticed you are using hungarian notation, which implies that txtFName is a TextBox. Keep in mind that C# doesn't have default properties like VB. If it is a TextBox, it will never equal "", because it's not of type System.String. I'm guessing you actually wanting to evaluate txtFName.Text
Change that last line to:
return false;
Although it seems you're always returning false here. Is there an option to return true?
Just a side note besides all the returns...
You may want to change this:
if txtFName != ""
To check if the String.IsEmptyOrNull(txtFName.Text)
Or at least initialize your variables to either null or String.Empty.
Just an FYI though.
You want to return false
Alright, taking the code you posted:
protected bool ValidateProfile()
{
return !String.IsNullOrEmpty(txtFName) && !String.IsNullOrEmpty(txtLName) && !String.IsNullOrEmpty(txtEMail);
}
Or
protected bool ValidateProfile()
{
bool returnValue = true;
if(String.IsNullOrEmpty(txtFName))
{
returnValue=false;
}
else if(String.IsNullOrEmpty(txtLName))
{
returnValue = false;
}
else if(String.IsNullOrEmpty(txtEMail))
{
returnValue = false;
}
return returnValue;
}
Though you could just return false as soon as you find an invalid field.
Not a C# programmer, but can't you just write:
return (txtFName != "") && (txtLName != "") && (txtEMail != "");
for the body of the function?

Categories

Resources