validating String.IsNullOrEmpty in C# with ternary operator - c#

the most of the time when I work with C# and need to validate a null or empty string I use the method:
if (String.IsNullOrEmpty(s))
return "is null or empty";
else
but now I need to use this in this way:
string value= data.value==null?DBNull.Value:data.value;
I try to use both in the last sentence getting this
string value= String.IsNullOrEmpty(data.value)?DBNull.Value:data.value;
but always return true even is there is not any value in the property data.value, BTW data.value is a string, could you please tell me if my sentence is right or what seems to be the problem?

First off you cant use string value = DBNull.Value because those types are not compatible. You have to cast back to the common type which is System.Object so then the assignment becomes this which uses casting to ensure type compatibility:
object value = String.IsNullOrEmpty(data.value)
? (object) DBNull.Value
: (object) data.value;
If you want to check for white space you can use IsNullOrWhiteSpace instead of IsNullOrEmpty

Related

Casting a null character reference ToString()

In C# .net, if I take a string.Empty and call .FirstOrDefault() on it, intending to get the first character of the string, It will return a null character reference i.e. \0, and not a null character i.e. char?. Then casting this ToString() does not have the same value as string.Empty
So based on my testing the following statements appear to resolve to true:
string.Empty.FirstOrDefault().ToString() != string.Empty
((char?)null).ToString() == string.Empty
string.Empty.FirstOrDefault().ToString() == '\0'.ToString()
Is it just me or does this feel inconsistent? This wasn't obvious to me initially and I had assumed that string.Empty.FirstOrDefault().ToString() would resolve to the same value as string.Empty. Can anybody link me to documentation that covers this gotcha in more depth?
string is an IEnumerable<char>, so FirstOrDefault() on an empty string returns default(char), not default(char?).
default(char) is '\0'.
It is (almost) impossible to write a generic method that works on references types but returns T? for value types (which is what you're expecting here).
string.Empty = "" is array of chars of length 0.
string.Empty.FirstOrDefault() is default(char) which is '\0' (FirstOrDefault<T> returns default(T) if source is empty)
string.Empty.FirstOrDefault().ToString() = default(char).ToString() = "\0"
char? is Nullable<char>, if you check ToString() implementation for Nullable
public override string ToString()
{
if (!this.hasValue)
return "";
return this.value.ToString();
}
which means, ((char?)null).ToString() returns "" (or string.Empty).

What is the difference between these 2 statements?

Possible Duplicate:
C# ?: Conditional Operator
statement first:
if(dr["AskingPriceFrom"]!=System.DBNull.Value)
objFilters.AskingPriceFrom=Convert.ToDecimal(dr["AskingPriceFrom"]);
else
objFilters.AskingPriceFrom=null;
statement second:
objFilters.AskingPriceFrom=Convert.ToDecimal(
dr["AskingPriceFrom"]!=System.DBNull.Value ? dr["AskingPriceFrom"] : null
);
What is difference between these two statements?
In first statement, if value is empty in if-else condition, then it stores null value correctly; but, if value is empty in the second condition, then instead of storing null value it stores 0. AskingPriceFrom is a get-set field stores decimal value. I tried to convert only dr["AskingPriceFrom"] after the question mark but the statement gives me an error.
Is there any way to protect null value from converting in decimal?
Apparently Convert.ToDecimal(null) == 0
//Edit: This should work
objFilters.AskingPriceFrom =
(dr["AskingPriceFrom"] != System.DBNull.Value) ?
Convert.ToDecimal(dr["AskingPriceFrom"]) : null;
It's because Decimal is not nullable. You should cast to decimal? so that when you convert a null to that type it will not return the default value 0 but instead return null.
in the inline version(ternary)
if it is null you will get:
objFilters.AskingPriceFrom = Convert.ToDecimal(null);
this will probably result an error.
You should read Convert.ToDecimal documentation here http://msdn.microsoft.com/en-us/library/e6440ed8.aspx.
Convert.ToDecimal returns decimal or throws exception, but in your case you need return type as Nullable<decimal>.
You can use code like this:
decimal? result;
if (Convert.IsDBNull(dr["AskingPriceFrom"]))
{
result= null;
}
else
{
result = dr.GetDecimal(reader.GetOrdinal("AskingPriceFrom"));
}
Thanks a lot to https://stackoverflow.com/users/1336654/jeppe-stig-nielsen. This is working properly.
objFilters.AskingPriceFrom = dr["AskingPriceFrom"] != System.DBNull.Value ? Convert.ToDecimal(dr["AskingPriceFrom"]) : (decimal?)null;

Trim Textbox value by considering NULL

Can you tell me if TrimNull() is redundant and if I should be using an alternative?
For example:
string username = UsernameTextBox.Text.TrimNull();
I am told there is no definition or extension method. Perhaps there is a reference I am missing?
UPDATE:
What is the most readable way to return empty string if the value is NULL?
There's no such function as TrimNull(String) - it wouldn't do anything. A string is either a null or not null, it can't contain a mixture of both. If the string were null, a static function TrimNull(myString) would not be able to 'remove' anything from the string. If it weren't null, there would be no NULL to remove. Even worse, if TrimNull were an instance method myString.TrimNull() would simply cause an exception if myString were NULL - because you cannot invoke any method on a null reference.
If your goal is to trim whitespace characters surrounding the string, just use myString.Trim().
If your goal is to detect whether the string is null, use myString == NULL
If your goal is to detect whether the string is empty or null use String.IsNullOrEmpty(myString)
If your goal is to trim trailing null characters (\0) from data stream, try the following:
myString.TrimEnd(new char[] { '\0' } )
But as Frédéric Hamidi said, if you're referring to the latter, the user will have a hard time getting null characters into a TextBox, so you shouldn't worry about that scenario in your processing of their input.
I usually use String.IsNullOrWhiteSpace(), like this:
string username = (String.IsNullOrWhiteSpace(UsernameTextBox.Text) ?
null : UsernameTextBox.Text.Trim());
That way, if the .Text property is null, it doesn't cause an exception.
You could create your own extension-method for that, if you like:
public static class StringExtensions
{
public static string TrimNull(this string value)
{
return string.IsNullOrWhiteSpace(value) ? value : value.Trim();
}
}
Add this to your project and your code will work.
This is just an alternative.
Use null-coalescing operator as mentioned in #sixlettervariables answer in Negate the null-coalescing operator
string username = (UsernameTextBox.Text ?? String.Empty).Trim();
A string being NULL is not its value. its a state. It means it has not been assigned a memory (coz its a reference type). Had it been a value type datatype it woudld be assigned a default value automatically like for int its 0 and so on
u should use
if(!String.IsNullOrEmpty(UsernameTextBox.Text))
string username = UsernameTextBox.Text.Trim();

How to check if String is null

I am wondering if there is a special method/trick to check if a String object is null. I know about the String.IsNullOrEmpty method but I want to differentiate a null String from an empty String (="").
Should I simply use:
if (s == null) {
// blah blah...
}
...or is there another way?
An object can't be null - the value of an expression can be null. It's worth making the difference clear in your mind. The value of s isn't an object - it's a reference, which is either null or refers to an object.
And yes, you should just use
if (s == null)
Note that this will still use the overloaded == operator defined in string, but that will do the right thing.
You can use the null coalescing double question marks to test for nulls in a string or other nullable value type:
textBox1.Text = s ?? "Is null";
The operator '??' asks if the value of 's' is null and if not it returns 's'; if it is null it returns the value on the right of the operator.
More info here:
https://msdn.microsoft.com/en-us/library/ms173224.aspx
And also worth noting there's a null-conditional operator ?. and ?[ introduced in C# 6.0 (and VB) in VS2015
textBox1.Text = customer?.orders?[0].description ?? "n/a";
This returns "n/a" if description is null, or if the order is null, or if the customer is null, else it returns the value of description.
More info here:
https://msdn.microsoft.com/en-us/library/dn986595.aspx
To be sure, you should use a function to check for null and empty as below:
string str = ...
if (!String.IsNullOrEmpty(str))
{
...
}
If you are using C# 7.0 or above you can use is null:
if (s is null) {
// blah blah...
}
Also, note that when working with strings you might consider also using IsNullOrWhiteSpace that will also validate that the string doesn't contain only spaces.
For .net 5 (probably also for .net Core 3.1)
Different possibility to write but always the same problem.
string wep = test ?? "replace";
Console.WriteLine(wep);
result: "replace"
or
string test=null;
test ??= "replace";
Console.WriteLine(test);
test="";
test??="replace";
Console.WriteLine(test);
first try: "replace"
second try: blank
string test="";
if(test is null)
Console.WriteLine("yaouh");
else
Console.WriteLine("Not yahouu");
Result: "Not yahou"
You can check with null or Number.
First, add a reference to Microsoft.VisualBasic in your application.
Then, use the following code:
bool b = Microsoft.VisualBasic.Information.IsNumeric("null");
bool c = Microsoft.VisualBasic.Information.IsNumeric("abc");
In the above, b and c should both be false.

What is the best practice for syntax in casting a variable?

Which (if any) is more correct? Why?
string someVariable = (string) someOtherVariable;
string someVariable = someOtherVariable.ToString();
string someVariable = someOtherVariable as string;
I've used all three, but I don't have any preference or understanding why one is better than the other.
These are not all examples of casting.
This is a cast:
string someVariable = (string) someOtherVariable;
This is method call:
string someVariable = someOtherVariable.ToString();
And this is a safe cast:
string someVariable = someOtherVariable as string;
The first and third examples are actual casts. The first cast has the potential to throw an InvalidCastException whereas the third example will not throw that exception. That is why the as operator is known as a safe cast.
Here's my article on the subject.
http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx
As for which one is "most correct", the one that is most correct is the one that has the meaning you intend to convey to the reader of the program.
"ToString()" conveys "this is probably not a string; if it is not, then I wish to obtain from the object a string which represents it."
The "cast" operator conveys either "this is a string, and I am willing to have my program crash if I am wrong", or the opposite, "this is not a string and I want to call a user-defined conversion on this object to string".
The "as" operator conveys "this might be a string and if it isn't, I want the result to be null."
Which of those four things do you mean?
The three do different things -- none are "more correct", it depends on your situation. If you have a bunch of objects that may not be strings, you'd probably use .ToString() (with a null check, if you expect nulls).
If you only care about the non-null strings, but still expect to be receiving non-strings, use an "as" cast, and then ignore the values that come in as null (they were either originally null, or of a non-string type)
if you expect to receive only strings, it is best to use the (string) cast. This expresses the intent best in the code.
object foo = 5;
string str = (string)foo; // exception
string str = foo as string; // null
string str = foo.ToString(); // "5"
object foo = "bar";
string str = (string)foo; // "bar"
string str = foo as string; // "bar"
string str = foo.ToString(); // "bar"
object foo = null;
string str = (string)foo; // null
string str = foo as string; // null
string str = foo.ToString(); // exception
The as keyword is very useful if you think the conversion will fail during an upcast. For instance, if I want to perform the same operation on similar types in a Control list... let's say unchecking all Checkboxes:
foreach (Control ctrl in Controls)
{
Checkbox box = ctrl as Checkbox;
if (box != null)
box.Checked = false;
}
This way, if my list has something else, like a text box or a label, no exception is thrown (as simply sets the variable = null if it fails), and it's very efficient. There is no exception overhead.
The ideas of CAST and CONVERT should not be confused here. Casting involves viewing an object as if it was another type. Converting involves transforming an object to another type.
If your intention is to CAST to a string, you should use the first or third. (Option depends on what you want to happen in the error condition. See bangoker's answer.)
If your intention is to CONVERT to a string, you should use the second. (Or better, ChaosPandion's modified statement with the trinary operator.) That is because the ToString method's behaviour is defined as converting the object into a string representation.
This is 100% personal preference here, but for me I use the folowing:
string someVariable = (string) someOtherVariable;
When converting to a child or parent type (eg. NetworkStream->Stream)
string someVariable = someOtherVariable.ToString();
When converting to a new type (int -> string)
And I never use the latter (as string) method, mostly because coming from a C/C++ background I prefer the() and it's a bit more concise.
There is a big difference between casting with parenthesis and casting with "as".
Basically, parenthesis will thrown an exception while "as" will return null instead of raising an exception.
More detailed info here
string someVariable = (string) someOtherVariable;
this is your good old normal casting and it will throw an exception if you try to cast something into something it CANNOT be casted (thus some times you need to check if they are castable)
string someVariable = someOtherVariable.ToString();
is not really casting, its executing a method that may come from different places(interfaces) but that ALL objects in C# have, since they inherit from the Object object, which has it. It has a default operation which is giving the name of the type of the object, but you can overload it to print whatever you want your class to print on the ToString method.
string someVariable = someOtherVariable as string;
This is a new c# casting, it will check first if it is castable by using a variable is string first and then doing the casting if it is valid or return null if it is not, so it could be a silent error if you are expecting exceptions, since you should check against null.
Basically
myType as myOtherType
is the same as:
var something = null;
if(myType is myOtherType)
{
something = (myType) myotherType;
}
except that as will check and cast in one step, and not in 2.
First of all, you should avoid casting with AS operator. The article linked explains why.
Second, you can use AS operator ONLY if you expect the value not being of the type you cast too. So you will have to check that manually.
Also the obj.ToString() method call is not a casting, it converts object to a string representation (which in case of a string itself is the same string). This can be ovveridden by any class.
So as a general rule I follow this:
Always use (Type) casting.
Use as operator only if object can be of other type than you cast to.
If using as operator - ALWAYS check the result for NULL.
UseToString only in cases when you need to display information about the object.
If your question about the best practice for syntax in casting a variable, then I prefer to use next one:
var someVariable = someOtherVariable as string ?? string.Empty;
Off course you can use someVariableDefaultValue instead of string.Empty.
In case if you cast not to string but into the some complex type, then I recommend next syntax, sometimes called the Safe Navigation Operator:
var complexVariable = otherComplexVariable as ComplexType;
if (complexVariable?.IsCondition)
{
//your code if cast passed and IsCondition is true
}
else
{
//your code if cast not passed or IsCondition is false
}

Categories

Resources