If I have two text boxes and I want to know if both of their Text properties are null I can do this:
if (string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
string.IsNullOrWhiteSpace(txtNameLast.Text))
{}
That will check if both are null or blank, but is there a way to say if not null or white space? Essentially, the inverse?
Put a ! before the string.IsNullOrWhiteSpace() method call.
if (!string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
!string.IsNullOrWhiteSpace(txtNameLast.Text))
{
// ...
}
There are several ways:
if (!string.IsNullOrWhiteSpace(txtNameFirst.Text) &&
!string.IsNullOrWhiteSpace(txtNameLast.Text))
{}
or
if (string.IsNullOrWhiteSpace(txtNameFirst.Text) == false &&
string.IsNullOrWhiteSpace(txtNameLast.Text) == false)
{}
or
if (txtNameFirst.Text?.Trim().Length > 0 &&
txtNameLast.Text?.Trim().Length > 0)
{}
As everyone else is saying, !string.IsNullOrWhiteSpace() will work for you.
Based on this question I assume you didn't know this, but the logical negation operator ! is a unary operator that negates its operand. It is defined for bool and returns true if and only if its operand is false.
So another example, let's say I want to see if the string The dog barked loudly contains the letter a, I would type string.Contains("a"). However, if I wanted to to make sure it does not contain the letter a, I would type !string.Contains("a").
Related
Am refactoring some old code and see something in the following format:
Type = rec["IsFlagged"]?.ToString() == "True" ? "Yes" : "No"
which should not work if rec["IsFlagged"] is null, in which case I need to return null. How would one refactor to keep code in one line, if possible?
I can do something like but am wondering if the following can be achieved in one line to have minimal changes to code
if (rec["IsFlagged"] != null)
{
return rec["IsFlagged"].ToString() == "True" ? "Yes" : "No"
}
else
{
return null
}
Thanks,
The original code works fine.
rec["IsFlagged"]?.ToString() == "True" ? "Yes" : "No"
The ? operator before .ToString() prevents the method from being called if null. The result of rec["IsFlagged"]?.ToString() would be null
Then, it compares null to "True" which is false (they are not equal).
The ternary operator then evaluates "No" and assigns it to the lvalue.
EDIT
So, now you want 3 possible results: "Yes", "No" or null. A single ternary only gives you two choices. There are many possibilities and yours is fine, unless you have multiple places doing something similar.
In that case, you could use an extension method:
public String CheckTrue(this object input) {
return input?.ToString() == "True" ? "Yes" : "No"
}
and then in your specific case:
return rec["IsFlagged"]?.CheckTrue()
Another alternative is to use multiple ternary operators?
return rec["IsFlagged"]==null ? null : (rec["IsFlagged"].ToString() == "True" ? "Yes" : "No");
This will do want you want..
rec["IsFlagged"]?.ToString().Replace("True","Yes").Replace("False","No")
.. but you perhaps shouldn't want to do it!
I prefer Garr's suggestions, though if it's a bool inside rec (is rec a DataRow?) I'd skip the ToString/compare with string and just use it as a bool once we know it's not null
return rec["IsFlagged"]==null ? null : ((bool)rec["IsFlagged"] ? "Yes" : "No");
But all in I like the extension method approach more, and we can tweak it some, leveraging conversion between a bool-or-null-stored-in-object and bool?:
public static string ToNullaboolString(this bool? x, string t = "Yes", string f = "No", string n = null){
if(x.HasValue)
return x.Value ? t: f;
return n;
}
Calling it like:
((bool?)rec["IsXxx"]).ToNullaboolString()
or supplying parameters if you want to change the strings returned (localization?)
I have a property in a class
public class User {
public string FiscalCode {get; set;}
}
And i want test the property fiscal code with two condition.
The test is ok if fiscalcode is null or fiscalcode is verified by a method
public bool FiscalCodeIsCorrect(string fiscalcode)
{
....
}
How can i test in a single line with shouldly if one of the two conditions is verified ?
I want use this condition in a test project so the line of code could be
user.FiscalCode.ShouldBeOneOf()
But i can't because null and string are two different types.
ShouldBeOneOf can not deal an function, so I think the simple way is using ShouldBeTrue
(FiscalCode == null || FiscalClodeIsCorrect(FiscalCode)).ShouldBeTrue();
I think you can just use basic ||:
if ( FiscalCode == null || FiscalCodeIsCorrect(FiscalCode) )
{
//something
}
|| is logical OR operator. This evaluates to true in case at least one of the operands evaluates to true. Also, note that it does short-circuiting which means if the FiscalCode is null it will not call FiscalCodeIsCorrect at all.
what #Martin Zikmund sugessted is right too but in your case both Null and FiscalCodeIsCorrect should be ok. So putting the null validation logic in FiscalCodeIsCorrect should be a better solution, then you wont have to validate if null every time.
so here is what i mean
public bool FiscalCodeIsCorrect(string fiscalcode)
{
if (fiscalcode == null)
return true;
//....You code here
}
now you only have to chack
if (FiscalCodeIsCorrect(FiscalCode) )
{
//something
}
I'm building a program that has to check if any of multiple variables are negative but it's telling me that Operator || cannot be applied to operands of type 'double' and 'double'.
if (ASUses || eleven52Uses || UreaUses || PotashUses || FillerUses<0)
{
MessageBox.Show("Error: one or more of the desired outputs is negative");
}
The problem only exists in the first two variables:
(ASUses || eleven52Uses)
Try this:
if (ASUses<0 || eleven52Uses<0 || UreaUses<0 || PotashUses<0 || FillerUses<0)
(Assuming that all variables are double numbers and not bools of course...)
The logical or operator (||) can only be applied to boolean values. While human logic can easily find out the meaning behind your syntax, the compiler can only read it if it adheres to the language specifications, unfortunately.
Also: I would consider writing a function which checks for validity of the variables and not use so many variables in the if statement, as it will be quite hard to maintain code like that.
That's not how it works, you need to separate each statement. or use an array:
if(new []{ ASUses,eleven52Uses,UreaUses,PotashUses,FillerUses }.Any(x => x < 0))
Also you need < 0 if you want to check for negative numbers
I am new to learning C# and Silverlight and have been given some application files by my employer to start learning. I am able to understand most of the logic, methods and syntax used in C# but there is one line which is very confusing to me. I dont have access to my seniors right now to ask them so the logic behind it so I thought I will ask here.
Take a look at this:
In a .xaml.cs file:
List<object> lst = new List<object>();
lst.Add(GP.mpl.A);
lst.Add(GP.mpl.B);
lst.Add(GP.mpl.C);
lst.Add(GP.mpl.StnNo);
In a different .cs file:
public int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
I understand that StnNo is being received from lst[3] and converted to Integer through
Convert.ToInt32(lst[3].ToString()
But I dont understand this part:
== string.Empty ? 0 : Convert.ToInt32(lst[3].ToString())
Could you tell me what's going on there? I have done multiple searches on google but didn't find anything related. Thanks for any help.
? is a ternary operator.
condition ? first_expression : second_expression;
?: Operator (C# Reference)
So in you example,
public int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
is equal to
public int StnNo;
if (lst[3].ToString() == string.Empty)
{
StnNo = 0;
}
else
{
StnNo = Convert.ToInt32(lst[3].ToString());
}
This is the conditional, sometimes referred to as ternary, operator.
It takes the form boolean expression ? true value : false value.
In C#, the true value and false value must be of the same type, or one must be implicitly convertible to the other (but not both). Otherwise, you must legally and explicitly cast one or both to a common type.
In your code, you have
int StnNo = Convert.ToInt32(lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()));
it is producing the functional equivalent of
int temp;
if (lst[3].ToString() == string.Empty)
temp= 0;
else
temp = Convert.ToInt32(lst[3].ToString());
int StnNo = Convert.ToInt32(temp);
You can see the outer Convert.ToInt32 in your code is actually redundant and can be eliminated.
int StnNo = lst[3].ToString() == string.Empty ? 0 : Convert.ToInt32(lst[3].ToString());
That's a very poorly written way of saying "if lst[3] is empty, then use 0, otherwise parse lst[3]" - because as your question illustrates, it's harder to tell what exactly the original developer intended.
To make it more clear, let's dissect it.
lst[3].ToString() == string.Empty means "does the lst[3] evaluate to an empty string?"
? X : Y means "if so, X, otherwise Y.
0 a constant value
Convert.ToInt32(lst[3].ToString()) parses the value as an lst[3] integer.
Finally the whole expression is passed into another Convert.ToInt32, but this is entirely unnecessary because the result of the conditional expression is always an int.
Since you don't have to call Convert.ToInt32 twice, a better way of writing this would be:
public int StnNo =
(lst[3].ToString() == string.Empty
? 0
: Convert.ToInt32(lst[3].ToString()));
An even better way of writing this would be:
int StnNo;
int.TryParse(lst[3], out StnNo);
It's more lines of code, but it's a lot easier to read.
== string.Empty ? 0 : Convert.ToInt32(lst[3].ToString()) is to check that if lst[3] does not contain any value, then 0 will be assigned to StnNo.
I often do this when necessary to prevent a null pointer exception:
// Example #1
if (cats != null && cats.Count > 0)
{
// Do something
}
In #1, I've always just assumed that the cats != null needs to be first, because order of operations evaluate from left to right.
However, unlike example #1, now I want to do something if the object is null or if the Count is zero, therefore I'm using logical OR instead of AND:
// Example #2
if (table == null || table.Rows == null || table.Rows.Count <= 0)
{
// Do something
}
Does the order of the logical comparisons matter? Or can I also reverse the order and get the same results, such as in Example #3?
// Example #3
if (table.Rows.Count <= 0 || table.Rows == null || table == null)
{
// Do something
}
(btw, I realize I can rewrite #2 like below, but I think it's messy, and I'm still curious about the OR operators)
// Example #4
if (!(table != null && table.Rows != null && table.Rows.Count > 0))
{
// Do something
}
In the example you provide:
if (table == null || table.Rows == null || table.Rows.Count <= 0)
{
// Do something
}
...neither table.Rows, nor table.Rows.Count, will be dereferenced if tables is null.
That's because, with C# logical operators, order of operations matter. C# logical operators are short-circuiting - they evaluate from left to right, and if any result causes the rest of the expression to be moot, the rest of the expression will not be evaluated.
Consider this code:
bool A()
{
return false;
}
bool B()
{
return true;
}
//...
if (A() && B())
{
// do something
}
For an AND clause to be true, all elements must be true. However, A() returns false, and the runtime (or maybe the compiler here, in an optimization step, but let's not worry about that...) won't evaluate B() at all.
The same holds true for OR (||) expressions. If any element in the clause is true, evaluated left to right, the rest of the clause won't be executed.
Yes, the short-circuiting happens in both cases, the only difference being that && stops if the LHS is false (because the overall expression must then be false) while || stops if the LHS is true (because the overall expression must be true).
The first two examples in your question are correct, the third will throw an exception if table or table.Rows are null.
You should note that not all C# logical operators exhibit short-circuting behaviour (as was indicated above).
You are using the Conditional-AND operator (&&) and that does short-circuit. However the AND (&) operator is exactly the same as the Conditional-AND without the short-circuit.
The same is true for the OR and Conditional-OR operators.
For Example:
//This will throw if cats is null, whatever order.
if (cats != null & cats.Count > 0){ }
//This will not. Due to short-circuting.
if (cats != null && cats.Count > 0){ }
The first construction is not the same as the second one. The first one is to use when you want to not do anything when the reference is null or Count is zero. The second construction would DO something when it is null or the count is zero... To make the second one the same as the first you would need to write:
if (table == null || table.Rows == null || table.Rows.Count <= 0 || )
{}
else
{
// Do something
}
And order does matter, even in the second one as you wrote it, it would crash if table was null when it tried to evaluate table.Rows.
Order matters. Its all about short circuiting. For ands, the first false it hits it stops evaluating, for ORs it stops as soon as it hits a true.
It will short circuit after the first evaulation and that is why you dont get the null pointer exception.
When you think about it think insert null for each object.
if (null== null || null.Rows == null || null.null.Count <= 0)
{
// Do something
}
Then evaluate each boolean
if( true || null.Rows == null || null.null.Count <=0)
If you see true that means stop. If you hit a "null". statement you will crash.
Example to illustrate a crash
if (null.null.Count <= 0 || null.Rows == null || null== null)
{
// CRASH... Do something
}
Order does not matter.
Clarification:
The order you place the statements in the IF statement will not affect whether or not the IF statement is gone into...and thus the result.
As another poster pointed out, it will however affect which ones are evaluated, but this doesn't affect the bottom line AFAIK.
Edit #JonHanna
I guess I looked at this from the perspective that the OP stated he is checking for NPE's prior when required (see the first line of his post). So if his code doesn't produce runtime errors, then order means nothing. I can't imagine why anyone would code an IF statement with a thought process of "if this IF statement causes a NPE" then it won't get evaluated...