Why string or object type don't support nullable reference type? [duplicate] - c#

This question already has answers here:
C# nullable string error
(5 answers)
Closed 8 years ago.
Look into following code block:
//Declaring nullable variables.
//Valid for int, char, long...
Nullable<int> _intVar;
Nullable<char> _charVar;
//trying to declare nullable string/object variables
//gives compile time error.
Nullable<string> _stringVar;
Nullable<object> _objVar;
While compiling code compiler gives following error message:
The type 'string'/'object' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'
I read it several times but still unable to understand. Can anyone clarify this? Why object or string dont support nullable reference type?

object and string are reference types, so they're already nullable. For example, this is already valid:
string x = null;
The Nullable<T> generic type is only for cases where T is a non-nullable value type.
In the declaration for Nullable<T> there is a constraint on T:
public struct Nullable<T> where T : struct
That where T : struct is precisely the part that constrains T to be a non-nullable value type.

Nullable<T> is defined as:
public struct Nullable<T> where T : struct
meaning: it only works on value-type T (excluding Nullable<TSomethingElse> itself).
You cannot use Nullable<T> on reference-types (or on Nullable<T>), but you don't need to since all reference-types (including object and string) are already "nullable", in that you can assign null to them.

string and object are reference types, and therefore are "nullable" already. The Nullable<T> type exists as a wrapper around value types that don't support null out of the box.
string myString = null //fine
int myInt = null //compiler error

Related

How can I initialize a System.Nullable<Int32>? [duplicate]

This question already has answers here:
GetType on Nullable Boolean
(2 answers)
Closed 1 year ago.
I need a Nullable type but how do I initialize such a variable? Whenever I try to do this it automatically converts to a normal Int32.
Nullable<Int32> nullableInt32 = new Nullable<Int32>(3);
Console.WriteLine(nullableInt32.GetType()); // gives me System.Int32
Is this a bug? How can I actually initalize the Nullable?
From Microsoft's documentation:
If you want to determine whether an instance is of a nullable value type, don't use the Object.GetType method to get a Type instance to be tested with the preceding code. When you call the Object.GetType method on an instance of a nullable value type, the instance is boxed to Object. As boxing of a non-null instance of a nullable value type is equivalent to boxing of a value of the underlying type, GetType returns a Type instance that represents the underlying type of a nullable value type.
So your int? gets boxed to int, and GetType() is called on the boxed instance.
Unless you know the type at compile time and use typeof, there is no way to get a type of a nullable object:
var type = typeof(int?);
In practice this shouldn't matter because if you don't know the type at compile time, it means you're using some sort of type erasure (i.e. a cast to object), and that means boxing, and nullable value types don't exist there. You can't use polymorphism because that doesn't work with value types.
If you think you have a valid need for this, feel free to explain your use case in the comments.

Nullable restrictions [duplicate]

This question already has answers here:
Why can't I write Nullable<Nullable<int>>?
(5 answers)
Closed 5 years ago.
Does anyone know why this code doesn't compile?
Nullable<Nullable<int>> n = null;
I realize Nullable has a constraint
where T : struct
But Nullable is struct. I also know this constraint has a restriction "The type argument must be a value type. Any value type except Nullable can be specified." (https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters).
So how does it work? Is this solved on compiler level?
The error message is:
The type int? must be a non-nullable value type in order to use it
as parameter 'T' in the generic type or method Nullable<T>
So it must not only be a value type but a non-nullable value type. But Nullable<int> is a nullable value type.
Here's the compiler error CS0453 which also shows this example:
This error occurs when you use a non-value type argument in
instantiating a generic type or method which has the value constraint
on it. It can also occur when you use a nullable value type argument.
Q: Is this solved on compiler level?
Yes, which means it' not very interesting to know how they achieved this constraint. It's an implementation detail of the compiler which doesn't need to use a C# language feature.
Why is not allowed?
Well, what would be the benefit of a Nullable<Nulable<int>>? Nullables were introduced to give value types the opportunity to be null(so undefined, without value). This is already achieved for a Nullable<int>, it can be null. So by nesting it in another nullable you would not get anything. It's not allowed for the same reason why you can't have a Nullable<string>, a string as every other reference type can already be null.

Are nullable value types just wrappers around the regular value type?

The reason I ask is that you can cast a nullable type to a regular type with the Value property. That makes me think that the regular type is just wrapped up in the nullable type.
Yes, it is a generic struct:
public struct Nullable<T> where T : struct, new()
This is probably more confusing if you've only seen the T? syntax - but that is just syntactic sugar, the compiler is changing it to Nullable<T>.
Source: http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx , http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
Yes - 'Nullable<T> Structure':
Represents an object whose underlying
type is a value type that can also be
assigned null like a reference type.
[BTW, if your curious you can use Reflector to 'look under the hood']
According to MSDN "Nullable types are instances of the System.Nullable<T> struct. A nullable type can represent the correct range of values for its underlying value type, plus an additional null value"

What does one question mark following a variable declaration mean? [duplicate]

This question already has answers here:
What is the purpose of a question mark after a value type (for example: int? myVariable)?
(9 answers)
Closed 6 years ago.
Whilst playing around in an open source project, my attempt to ToString a DateTime object was thwarted by the compiler. When I jumped to the definition, I saw this:
public DateTime? timestamp;
Might someone please enlighten me on what this is called and why it might be useful?
This is a nullable type. Nullable types allow value types (e.g. ints and structures like DateTime) to contain null.
The ? is syntactic sugar for Nullable<DateTime> since it's used so often.
To call ToString():
if (timstamp.HasValue) { // i.e. is not null
return timestamp.Value.ToString();
}
else {
return "<unknown>"; // Or do whatever else that makes sense in your context
}
? makes a value type (int, bool, DateTime, or any other struct or enum) nullable via the System.Nullable<T> type. DateTime? means that the variable is a System.Nullable<DateTime>. You can assign a DateTime or the value null to that variable. To check if the variable has a value, use the HasValue property and to get the actual value, use the Value property.
That is a shortcut for Nullable<DateTime>. Value types, like DateTime cannot be null; Nullable<> wraps the value type so that you have an object with a HasValue property and other convenient features.
it is nullable datetime

Do C# Nullable variables still function as value types?

If I declare a nullable (either via Nullable or the ? symbol) variable from a value type, does it still respect the rules of value types (i.e. pass by value by default, deallocated when it falls out of scope, not when the garbage collector runs) or does it turn into a reference type since it's actually of type Nullable?
The documentation is here:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx
As you can see, the documentation describes this as the "nullable structure", indicating that it is a value type. Also, the documentation gives the first lines of the declaration of the type:
public struct Nullable<T> where T : struct, new()
again showing that the type is a value type.
Yes, System.Nullable is a generic Struct, ie value type.
Nullable value types are essentially just a struct wrapper around a value type which allows them to be flagged as null.
something like this:
struct Nullable<T>
{
public T Value;
public bool HasValue;
}
I believe it's actually more complex than that under the hood, and the compiler does lots of nice stuff for you so you can write for example if(myInt == null). But yes, they are still value types.

Categories