Is there any reason to use this Regex method over String.IsNullOrEmpty()? - c#

I have a method called isStringOnlyWhitespace():
public static bool isStringOnlyWhitespace(string toEval)
{
string stringNoWhitespace = Regex.Replace(toEval, #"\s", "");
if (stringNoWhitespace.Length > 0) return false;
else return true;
}
Is there any reason to use this method to check for blank/null strings over String.IsNullOrEmpty()?

Sure, if you are shooting for slower code that is harder to read :)
You really want to use string.IsNullOrWhitespace though. Whoever wrote that code might have done so before this method existed. But even still, I'd prefer myString.Trim().Length == 0 in that case.

The method you give doesn't handle nulls whereas String.IsNullOrEmpty does.
That would indicate to me that passing your method a null value is an error condition which is different behavior from String.IsNullOrEmpty.
Also, as others have pointed out, your method would return true for isStringOnlyWhitespace(" ") whereas String.IsNullOrEmpty(" ") would return false.

Yes. Strings containing only whitespace are not considered to be empty. isStringOnlyWhitespace(" ") returns true, but string.IsNullOrEmpty(" ") returns false.

No ;)
a) I think since .net 4 you can use string.IsNullOrWhitespace
b) try something like
public static bool IsStringOnlyWhitespace(this string str)
{
// if you want to check for null:
return str == null || string.IsNullOrEmpty(str.Trim());
// else
return string.IsNullOrEmpty(string.Trim());
}

Related

How do you check for nullable value in an if statement

I have the following code:
string thing="";
if(request.Session.Attributes?.TryGetValue("varName", out thing))
{
//do stuff
}
request.Session.Attributes is a dictionary.
I understand that you can't have if(bool?) which is what the above does.
I also know that you can have .GetValueOrDefault() so that null will be treated as false.
But I can't do request.Session.Attributes?.GetValueOrDefault().TryGetValue("varName", out thing)
So what is the correct way to return false if Attributes is null otherwise return the bool from the TryGetValue?
A quick and slightly dirty way is doing:
string thing="";
if(request.Session.Attributes?.TryGetValue("varName", out thing) ?? false)
{
//do stuff
}
In this way you are sure that if Attributes is null, the second branch of the ?? will be chosen and it will not get inside the if.
Personally, I would split it, as having it in a 1-liner does not improve the code that much. It'd become:
string thing="";
var attributes = request.Session.Attributes;
if(attributes != null && attributes.TryGetValue("varName", out thing))
{
//do stuff
}
This is much more readable. Sometimes it is just fair to avoid using new features of the language if they do not improve the code.
Bonus tip:
You can get a line back removing the declaration of things and placing it just after the out 😉:
attributes.TryGetValue("varName", out string thing)
I suspect you're looking for:
if (request.Session.Attributes?.TryGetValue("varName", out thing) == true)
Alternatively:
if (request.Session.Attributes?.TryGetValue("varName", out thing) ?? false)
The null-coalescing ?? operator here is effectively saying "If we didn't call TryGetValue because Attributes is null, this is what I want to pretend it returned."
to set a default value of an nullable type in c# you can use the ?? opperator
if(nullableboolean ?? false){
}
so that would default to false
Something like this:
Dictionary<string,string> stuff = null;
if(stuff?.TryGetValue("key",out string val) ?? false){
Console.WriteLine("hey");
}

c# multiple if conditions in same lane

I have a slight problem when working with c# and using IF statments with multiple conditions.
This is the most common occurance.
private void SomeFunction(string SomeString)
{
if(SomeString != null && SomeString.Trim() != "")
{
}
}
In some languages like javascript if the first argument fails (SomeString != null) the second check wont be made. C# seems to check both arguments even if the first one fails and then the second one will throw an exception since you cannot use .Trim() on a null value.
Right now I am going over this by nesting my ifs which is messy work. Like this:
private void SomeFunction(string SomeString)
{
if(SomeString != null)
{
if(SomeString.Trim() != "")
{
.....
}
}
}
Does anybody have any suggestions or best practices on a better way to solve this?
C# seems to check both arguments even if the first one fails
That's not true, see && Operator (C# Reference) in MSDN.
Your assumption is totally wrong. When you use the conditional AND if the first condition is FALSE the second condition is never evaluated or executed. In the conditional OR if the first condition is TRUE the second one is never evaluated or executed.
In other words, if the compiler has enough info to determine the result of the expression it stops to consider the second part of the expression.
This is known as short-circuit evaluation.
It is a basic programming principle for C derived languages but also for every other major language.
There is a better way:
private void SomeFunction(string SomeString)
{
if (!string.IsNullOrWhiteSpace(SomeString))
{
// your code
}
}
if (!String.IsNullOrEmpty(SomeString))
{
}
if(!string.IsNullOrEmpty(SomeString))
similar to ProgramFOX prefer this if you insist on doing ".Trim()"

Negate the null-coalescing operator

I have a bunch of strings I need to use .Trim() on, but they can be null. It would be much more concise if I could do something like:
string endString = startString !?? startString.Trim();
Basically return the part on the right if the part on the left is NOT null, otherwise just return the null value. I just ended up using the ternary operator, but is there anyway to use the null-coalescing operator for this purpose?
You could create an extension method which returns null when it tries to trim the value.
public String TrimIfNotNull(this string item)
{
if(String.IsNullOrEmpty(item))
return item;
else
return item.Trim();
}
Note you can't name it Trim because extension methods can't override instance methods.
Not to spec: Not that I like it, but you could use:
string endString = (startString ?? String.Empty).Trim();
To spec, better as an Extension method like #Kevin's:
string endString = (startString == null ? null : startString.Trim());
string endString = string.IsNullOrEmpty(startString) ? startString : startString.Trim();
Though I've also gone the route of writing a string extension method called "safeTrim" which does what you're describing in one method instead of having to use this recipe every time. Check out Kevin's respone for the code.
EDIT: wow I had it all kinds of backwards, wrongly named variables and reversed ternary operators, all the more reason to write one extension method and code check it better than I did!
Starting with C# 6.0 (.NET Framework 4.6 / Visual Studio 2015) you can use null-conditional member access:
string? endString = startString?.Trim();
Sorry for the necromancy, but I was having this same problem and I solved this using a lambda operation. It isn't the prettiest, but it keeps my code succinct.
It's a shame C# doesn't support static imports or individual function imports, but anyway:
Define this function somewhere:
private static TResult N<TParent,TResult>(TParent parent, Func<TParent,TResult> operation) {
if( parent == null ) return default(TResult);
return operation( parent );
}
Then to use it in your example:
String endString = N(startString, s => s.Trim());
The N function returns null if the first argument is null, otherwise it will evaluate the specified lambda function with the value as the argument.
You can nest it, of course, like so. For example, to safely dereference a long chain, e.g.
String someValue = someObject.SomeProperty.SomeOtherProperty.SomeMethod().SomeFinalProperty;
if any of those properties or methods returns null then you have to insert null checks everywhere, or you could do this:
String someValue = N(N(N(N(someObject, o => o.SomeProperty), o => o.SomeOtherProperty), o => o.SomeMethod()), o => o.SomeFinalProperty);
As I said, it isn't the prettiest :)
You could simplify this by making N an extension method of System.Object, like so:
String someValue = someObject.N( o => o.SomeProperty ).N( o => o.SomeOtherProperty ).N( o => o.SomeMethod() ).N( o => o.SomeFinalProperty );
...which I think is a lot tidier.
Use
string endString = (startString ?? "").Trim();
This uses an empy string if startString is null. This, however, does not return null when endString is null.
Fast-forward to 2021:
10 years later startString?.Trim() is definitely the better option. And this does return null.
The following doesn't propagate null but it accepts null as a parameter and returns an empty string in that case.
using Microsoft.VisualBasic; // you need to add a reference to Microsoft.VisualBasic.dll
...
string endString = Strings.Trim(startString);
...
duck&run...
As as side note, if you're using .NET 4, there's a new convenient method String.IsNullOrWhiteSpace which you can use.

Null and blank values

What's the best way of writing robust code so that a variable can be checked for null and blank.
e.g.
string a;
if((a != null) && (a.Length() > 0))
{
//do some thing with a
}
For strings, there is
if (String.IsNullOrEmpty(a))
You can define an extension method to allow you to do this on many things:
static public bool IsNullOrEmpty<T>(this IEnumerable <T>input)
{
return input == null || input.Count() == 0;
}
It already exists as a static method on the System.String class for strings, as has been pointed out.
And if you are using .NET 4.0 you might want to take a look at String.IsNullOrWhiteSpace.
From version 2.0 you can use IsNullOrEmpty.
string a;
...
if (string.IsNullOrEmpty(a)) ...
if(string.IsNullOrEmpty(string name))
{
/// write ur code
}
for strings:
string a;
if(!String.IsNullOrEmpty(a))
{
//do something with a
}
for specific types you could create an extention method
note that i've used HasValue instead of IsNullorEmpty because 99% of the times you will have to use the !-operator if you use IsNullOrEmpty which I find quite unreadable
public static bool HasValue(this MyType value)
{
//do some testing to see if your specific type is considered filled
}
I find Apache Commons.Lang StringUtils (Java)'s naming a lot easier: isEmpty() checks for null or empty string, isBlank() checks for null, empty string, or whitespace-only. isNullOrEmpty might be more descriptive, but empty and null is, in most cases you use it, the same thing.

Convert.ToBoolean("1") throws System.Format Exception in C#

Why does
Convert.ToBoolean("1")
throw a System.FormatException?
How should I proceed with this conversion?
Yes, this is as documented:
[throws] FormatException [if] value is not equal to TrueString or FalseString.
TrueString is "True" and FalseString is "False".
If you want to detect whether a string is "1" or not, use this code:
bool foo = text == "1";
Depends on what you want. Perhaps
var result = Convert.ToInt32(yourstirng) != 0
assuming any number but 0 is true. Otherwise a simple comparison would work.
var result = yourstirng == "1"
The parameter must be equal to either Boolean.TrueString or Boolean.FalseString. The values of these strings are "True" and "False", respectively. See MSDN.
The string value "1" is obviously not equal to "True" or "False".
The problem is, that youre giving a String here, not a number. It cant convert the String "1" to true, but the int 1.
Convert.ToBoolean(1);
should work.
When converting to Boolean it is best to use your own routine, where you handle all cases. .net Convert.ToBoolean isn't a practical routine, it is one of those function where you have to explain why it doesn't work.
I know this is old, but in case someone searches... simply do this:
Convert.ToBoolean(Convert.ToInt16("1")) works just fine. Not pretty, but needs be.
Another solution is to use an Extension Method on the string object. I used this technique in a case where I had to parse CSV files that had different strings that had to be converted to boolean values depending on their source and format.
public static class StringExtensions
{
public static bool ToBool(this string value,string trueValue)
{
if (value == trueValue)
{
return true;
}
else
{
return false;
}
}
}
This would be called like so...
MyProperty = CsvColumn[6].ToBool("1");
If you want, the truevalue parameter could be a string array if you needed to compare multiple values (like n/a, na, none) and you could add in false values if you want to further restrict it or use nullable types.

Categories

Resources