Casting a null character reference ToString() - c#

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).

Related

validating String.IsNullOrEmpty in C# with ternary operator

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

C#-Warning 2 Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'

if ((Session["UserName"] != null && Session["LoginType"] == "Admin") || (Session["UserName"] != null && Session["LoginType"] == "Employee"))
{
TotalMarketBalance();
}
I suggest to change the if-statement to this:
if (Session["UserName"] != null &&
(Session["LoginType"] as string == "Admin" ||
Session["LoginType"] as string == "Employee")
)
Session[string key] returns an object. And if you compare an object to something using ==, you do a reference comparison. And the string literal ("Admin" for example) will never have the same reference like that object, even if this object is a string.
By casting the object into a string, the compiler knows that it has to call the equality methods of string, which compare the string's contents instead of their references.
Of course you can do a direct cast ((string)Session["LoginType"]) or call ToString(), too. But the first will throw an exception if (for some strange reason) the return object is not a string. The second will throw a NullReferenceException if (for some strange reason) the value is still null.
Change Session["LoginType"] to Session["LoginType"].ToString()
you can also cast to string:
(string)Session["LoginType"] == "Admin"
This is how the example is done in the Documentation Reading Values From Session State

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.

Difference between .ToString and "as string" in C#

What is the difference between using the two following statements? It appears to me that the first "as string" is a type cast, while the second ToString is an actual call to a method that converts the input to a string? Just looking for some insight if any.
Page.Theme = Session["SessionTheme"] as string;
Page.Theme = Session["SessionTheme"].ToString();
If Session["SessionTheme"] is not a string, as string will return null.
.ToString() will try to convert any other type to string by calling the object's ToString() method. For most built-in types this will return the object converted to a string, but for custom types without a specific .ToString() method, it will return the name of the type of the object.
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;
string s = o1 as string; // returns "somestring"
string s = o1.ToString(); // returns "somestring"
string s = o2 as string; // returns null
string s = o2.ToString(); // returns "1"
string s = o3 as string; // returns null
string s = o3.ToString(); // returns "System.Object"
string s = o4 as string; // returns null
string s = o4.ToString(); // throws NullReferenceException
Another important thing to keep in mind is that if the object is null, calling .ToString() will throw an exception, but as string will simply return null.
The as keyword will basically check whether the object is an instance of the type, using MSIL opcode isinst under the hood. If it is, it returns the reference to the object, else a null reference.
It does not, as many say, attempt to perform a cast as such - which implies some kind of exception handling. Not so.
ToString(), simply calls the object's ToString() method, either a custom one implemented by the class (which for most in-built types performs a conversion to string) - or if none provided, the base class object's one, returning type info.
I'm extending Philippe Leybaert's accepted answer a bit because while I have found resources comparing three of these, I've never found an explanation that compares all four.
(string)obj
obj as string
obj.ToString()
Convert.ToString(obj)
object o1 = "somestring";
object o2 = 1;
object o3 = new object();
object o4 = null;
Console.WriteLine((string)o1); // returns "somestring"
Console.WriteLine(o1 as string); // returns "somestring"
Console.WriteLine(o1.ToString()); // returns "somestring"
Console.WriteLine(Convert.ToString(o1)); // returns "somestring"
Console.WriteLine((string)o2); // throws System.InvalidCastException
Console.WriteLine(o2 as string); // returns null
Console.WriteLine(o2.ToString()); // returns "1"
Console.WriteLine(Convert.ToString(o2)); // returns "1"
Console.WriteLine((string)o3); // throws System.InvalidCastException
Console.WriteLine(o3 as string); // returns null
Console.WriteLine(o3.ToString()); // returns "System.Object"
Console.WriteLine(Convert.ToString(o3)); // returns "System.Object"
Console.WriteLine((string)o4); // returns null
Console.WriteLine(o4 as string); // returns null
Console.WriteLine(o4.ToString()); // throws System.NullReferenceException
Console.WriteLine(Convert.ToString(o4)); // returns string.Empty
From these results we can see that (string)obj and obj as string behave the same way as each other when obj is a string or null; otherwise (string)obj will throw an invalid cast exception and obj as string will just return null. obj.ToString()
and Convert.ToString(obj) also behave the same way as each other except when obj is null, in which case obj.ToString() will throw a null reference exception and Convert.ToString(obj) will return an empty string.
So here are my recommendations:
(string)obj works best if you want to throw exceptions for types that can't be assigned to a string variable (which includes null)
obj as string works best if you don't want to throw any exceptions and also don't want string representations of non-strings
obj.ToString() works best if you want to throw exceptions for null
Convert.ToString(obj) works best if you don't want to throw any exceptions and want string representations of non-strings
EDIT: I've discovered that Convert.ToString() actually treats null differently depending on the overload, so it actually matters that the variable was declared as an object in this example. If you call Convert.ToString() on a string variable that's null then it will return null instead of string.Empty.
Page.Theme = Session["SessionTheme"] as string;
tries to cast to a string
whereas
Page.Theme = Session["SessionTheme"].ToString();
calls the ToString() method, which can be anything really. This method doesn't cast, it should return a string representation of this object.
To confuse the matter further, C# 6.0 has introduced the null-conditional operator. So now this can also be written as:
Page.Theme = Session["SessionTheme"]?.ToString();
Which will return either null or the result from ToString() without throwing an exception.
First of all "any-object as string" and "any-object.ToString()" are completely different things in terms of their respective context.
string str = any-object as string;
1) This will cast any-object as string type and if any-object is not castable to string then this statement will return null without throwing any exception.
2) This is a compiler-service.
3) This works pretty much well for any other type other than string, ex: you can do it as any-object as Employee, where Employee is a class defined in your library.
string str = any-object.ToString();
1) This will call ToString() of any-object from type-defination. Since System.Object defines ToString() method any class in .Net framework has ToString() method available for over-riding. The programmer will over-ride the ToString() in any-object class or struct defination and will write the code that return suitable string representation of any-object according to responsibility and role played by any-object.
2) Like you can define a class Employee and over-ride ToString() method which may return Employee object's string representation as "FIRSTNAME - LASTNAME, EMP-CDOE" .
Note that the programmer has control over ToString() in this case and it has got nothing to do with casting or type-conversion.
The as string check is the object is a string. If it isn't a null it returned.
The call to ToString() will indeed call the ToString() method on the object.
The first one returns the class as a string if the class is a string or derived from a string (returns null if unsuccessful).
The second invokes the ToString() method on the class.
Actually the best way of writing the code above is to do the following:
if (Session["SessionTheme"] != null)
{
Page.Theme = Session["SessionTheme"].ToString();
}
That way you're almost certain that it won't cast a NullReferenceException.

Categories

Resources