WHY Nullable<T>,struct, allows 'null' - c#

Nullable is an struct. And i know structs cant be assigned 'null'. So how could we assign Nullable's object a null? What is the reason?

It doesn't actually accept a value of null; it simply has syntactic sugar that allows it to act like it's null. The type actually looks a bit like this:
struct Nullable<T>
{
private bool hasValue;
private T value;
}
So when it's initialized hasValue == false, and value == default(T).
When you write code like
int? i = null;
The C# compiler is actually doing this behind the scenes:
Nullable<T> i = new Nullable<T>();
And similar checks are made when casting null to an int? at run-time as well.
Further Reading
Why can assign “null” to nullable types

Related

Making value type variables nullable by using "?": does it imply boxing?

Given the following assumptions in C#:
boxing and unboxing let me convert any value type variable to an object type, which is a reference type (therefore it's also nullable), like in the example:
int i = 123;
object box = i;
The "?" operator let me convert a not-nullable integer into a nullable variable, like in the example:
int? n = 0;
My Question: for only reference type variables are nullable, can I say that in the second example I'm doing implicit boxing? In other terms, when I use the "?" operator to make nullable an integer, is there boxing operation implied as well (even if it's not explicit)?
int? is suggar for Nullable<T> See documentation. If we look at the signature of this we see:
public struct Nullable<T> where T : struct
{
...
public override bool Equals(object other)
{
if (!this.hasValue)
return other == null;
return other != null && this.value.Equals(other);
}
Since it is a struct the value will not be boxed.
If you need to compare values, n.Equals(1) would cause boxing of the argument. I cannot find any documentation about the equality operator ==, but I think it would be fairly safe to assume that it should not cause boxing.

How Nullable<T> = null works?

int? num = null;
How does it work under the hood? I always assumed Nullable is a class and today I was debugging and was surprised to see it's a struct. I checked the source code and found this implicit operator:
[System.Runtime.Versioning.NonVersionable]
public static implicit operator Nullable<T>(T value)
{
return new Nullable<T>(value);
}
It's obviously not the answer here since null is not an int. In addition the constructor is this:
[System.Runtime.Versioning.NonVersionable]
public Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
So the constructor is not called either.
Is compiler using some synthetic sugar here?
type? t = null;
is recognized by the compiler and replaced with type? t = new type?(), which invokes the default constructor which in turn sets the object to all zeros. The property HasValue is backed by a boolean variable such that false is the correct initial value in this case.
In just about every place, these constructions are treated as though they were references to a an object of type type. In order to observe they aren't you would need a mutable struct. The compiler knows about type? in quite a few ways including checking the HasValue property when boxing and boxing to a null or a boxed type. If you manage to get a boxed type? the unboxer should be able to handle it, but there doesn't seem to be a way to get a boxed type? anymore unless you're writing extern functions.

What does the bool? return type mean?

I saw a method return bool?, does anyone know the meaning of it?
T? is a C# syntax shortcut to Nullable<T>. So bool? maps to Nullable<bool>. So in your case it's a struct that either is null, or has a bool value.
If a Nullable<T> is null that's a bit different from a reference type being null. It basically is a struct containing the underlying type and a boolean flag HasValue. But both the runtime and the C# language have a bit of magic to pretend that a Nullable with HasValue==false is really null. But the difference still leaks sometimes.
The underlying type is implicitly convertible to the nullable type (bool->bool?). To get the underlying type from the nullable type, you can either cast explicitly ((bool)myNullableBool or use the Value property (myNullableBool.Value). You should check for null before though, or you'll get an exception if the nullable value is null.
Nullable Types (C# Programming Guide)
Nullable<bool>
In C#, the "primitive" types can't hold a null value:
int blah = null;
That will make an exception because 'int' can't hold a null value.
Same with double, float, bool, DateTime...
That is fine really. The problem comes when you are using databases. In a database you can have rows that can be null, like Age (that is an int).
How do you hold that row on an object? Your int cannot hold the null value and the row can have null.
For that reason MS created a new struct, the Nullable, you can pass to that struct a "primitive" type (or a struct) to make it nullable like:
Nullable<int> blah = null;
That will not make an exception, now, that variable can hold an int and a null.
Because Nullable is too long, MS created some kind of alias: If you put the '?' after the type, it becomes nullable:
int? blah = null;
Nullable<int> blah = null;
This two lines are EXACTLY the same but the first one is easier to read.
Something like that :)
Any (no-nonsense1) value type suffixed with ? makes it a nullable type:
int? is a nullable integer
bool? is nullable boolean which makes is actually a triple state boolean (true, false and null) - think of it when you need to implement some triple state behaviour.
...
In other words object type doesn't support nullable definition as object? because it's reference type and can have a value of null already.
Real-life usage
Nullable types are most often used against database, because they make it really easy to transform nullable int/bit/datetime/etc. columns to CLR types. Like in this example:
create table Test
(
Id int identity not null primary key,
Days int null,
ExactDate datetime null,
Selected bit null
)
This can easily be translated to POCO:
public class Test
{
public int Id { get; set; }
public int? Days { get; set; }
public DateTime? ExactDate { get; set; }
public bool? Selected { get; set; }
}
1 no-nonsense refers to all value types except Nullable<T> which is a value type per se, but it wouldn't make any sense in making it nullable once more... Avoid such stupidity... It won't compile anyway because Nullable<Nullable<int>> i = null; can be interpreted in two ways:
• i.HasValue == false
• i.HasValue == true && i.Value.HasValue == false

Making a Non-nullable value type nullable

I have a simple struct that has limited use. The struct is created in a method that calls the data from the database. If there is no data returned from the database I want to be able to return a null, but Visual Studio complains, Cannot convert null to PackageName.StructName because it is a non-nullable value type.
How can I make it nullable?
You want to look into the Nullable<T> value type.
public struct Something
{
//...
}
public static Something GetSomethingSomehow()
{
Something? data = MaybeGetSomethingFrom(theDatabase);
bool questionMarkMeansNullable = (data == null);
return data ?? Something.DefaultValue;
}
The definition for a Nullable<T> struct is:
struct Nullable<T>
{
public bool HasValue;
public T Value;
}
It is created in this manner:
Nullable<PackageName.StructName> nullableStruct = new Nullable<PackageName.StructName>(params);
You can shortcut this mess by simply typing:
PackageName.StructName? nullableStruct = new PackageName.StructName(params);
See: MSDN
Nullable<T> is a wrapper class that creates a nullable version of the type T. You can also use the syntax T? (e.g. int?) to represent the nullable version of type T.
Use the built-in shortcuts for the Nullable<T> struct, by simply adding ? to the declaration:
int? x = null;
if (x == null) { ... }
Just the same for any other type, struct, etc.
MyStruct? myNullableStruct = new MyStruct(params);
You could make something nullable for example like this:
// Create the nullable object.
int? value = new int?();
// Check for if the object is null.
if(value == null)
{
// Your code goes here.
}
You can use default as an alternative
public struct VelocityRange
{
private double myLowerVelocityLimit;
private double myUpperVelocityLimit;
}
VelocityRange velocityRange = default(VelocityRange);

why some unity source code assign null has a cast operation?

Recently,i found some code like Material s_DefaultUI = (Material) null; in Unity Graphic source code.But i don`t know why there has a cast operation.what's the benefit ?Thanks for your help!
Casting null to a nullable type, in a assignment to a explicitly typed variable, doesn't do anything and doesn't change anything, it's the same as not casting it at all, the only times when casting null to a type has a "benefit" is when:
1) You have multiple signatures of the same method which have different nullable types on the same position, e.g.:
void CheckIfNull(string s);
void CheckIfNull(Material m);
In this case, doing CheckIfNull(null) won't work because, it doesn't know to which sig the specified null should be passed to, so doing CheckIfNull((Material)null) will solve the issue.
2) If you have a value type which accepts a nullable type via a explicit conversion, e.g.:
struct StructA
{
public StructA(object obj) { }
public static explicit operator StructA(object obj)
{
return new StructA(obj);
}
}
void Stuff()
{
StructA myStruct = (StructA)null;
}
3) When using a implicitly typed variable, if s_DefaultUI was a var you would need to cast the null because, var is a auto type so it wouldn't know what the provided null's type is.
Other then that, AFAIK, there is no point in casting a null to a type, especially to a class type.

Categories