I am just wondering what is the difference between the two next statements:
Causes a NullReferenceException - it is OK.
object test1 = default(int?);
object result = test1.ToString();
Returns an empty string "", why?
object test2 = default(int?).ToString();
This is same as 2.
int? test3 = null;
if (test3.ToString() == string.Empty) //returns true
{
Console.WriteLine("int? = String.Empty, isn't it strange?").
}
And just for fun - I can prove that bool can be equal to int value (hmmm how? bool can be only false, or true and int never can be that).
if (default(int?).ToString() == default(bool?).ToString()) //returns true because both are empty strings
{
Console.WriteLine("int = bool");
}
Note: default(int?) returns null.
Returns: a string representation of the object. In other words null is not a defined return value. If you don't override the toString() method then you will always get a string that at least gives you the Object's ID.
An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters. A null string is represented by null .
So, NULL is better. An empty string is useful when the data comes from multiple resources. NULL is used when some fields are optional, and the data is unknown.
str = str. replace(null,""); As String is immutable in java, you need to assign the result either to new String or same String. String's replace() method returns a string replacing all the CharSequence to CharSequence.
An int?
is a Nullable<int>
. Nullable
is a struct, which makes it a value type, not a reference type. test3
isn't actually set to null
. Assigning null
to it actually results in the creation of a new structure that simply has the HasValue
field of that struct set to false
instead of true
. (Special compiler support is required for such an implicit conversion to take place; so you couldn't have your own MyNullable<T>
type that did this.)
Since the nullable object has an actual value, it can call ToString
and provide a meaningful value, in this case, an empty string.
When you box that nullable value by putting it in an object
variable it will result in an actual null
value being stored in that variable, which is why you get a NRE when calling a method on it.
When a nullable value type is boxed it doesn't box the nullable value type; instead if it has no value it assigns null
to the object, if it has a value then that underlying value is unwrapped and then boxed. (Special support from the runtime is required for this behavior, which is another reason why you can't make your own MyNullable<T>
type.)
In C, one uses the token .
to access a member of the left operand, and ->
to access a member of the thing to which the left operand holds a pointer (reference). A null reference occurs if the left-hand operand of ->
is null. In C#, the .
has the former meaning when applied to value types and the latter meaning when applied to class types; using .
in C# on a class type variable which is null will trigger a NullReferenceException
.
The .NET type Nullable<T>
is a two-field structure which contains Boolean field which indicates whether it has a meaningful (non-null) value, and field of value type T
to say what that value is (if not null). Although the compiler will allow one to assign a Nullable<T>
to null or compare one with null, the null
in the former case is really just shorthand for a default instance (where the "has-value" flag is false, and the value field holds the default value for type T), and the comparison to null is really just a shorthand for checking the HasValue
property (which in turn looks at the Boolean
field). Invoking ToString
on e.g. a Nullable<int>
which is "null" is no different semantically from invoking it on any other structure that contains a Boolean
and an Int32
which have the values False
and 0
, respectively. There are a few ways in which compilers treat nullable types "specially", but a default-valued Nullable<int>
holds [False, 0]
, not a null reference.
Note that the first example throws because of one of the "special" rules the framework applies to nullable types. Casting a value type to Object
or another reference type generally instructs the runtime to create an object that will behave as a class object with fields and members matching those of the struct and return a reference to that new object--a process known as "boxing". Because the designers of nullable types wanted to allow code to say if (NullableThing == null)
rather than the (IMHO sematically clearer) if (!NullableThing.HasValue)
, the runtime was implemented so that boxing a nullable whose HasValue
field is false will yield a null reference rather than a reference to a default-valued instance of Nullable<T>
. While I think there are cases where would make sense to have some value types use different box and unbox methods, nullable types are the only ones that can use anything other than normal boxing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With