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

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

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.

Alternative to IsNullOrEmpty for nullable types?

Is there a way to use IsNullOrEmpty with nullable types? The code above generates a build error when using IsNullOrEmpty with string? RunDate
public int MyMethod(string? RunDate = null)
{
string sql = string.Empty;
int rowsChanged = -1;
if (String.IsNullOrEmpty(RunDate))
{
//do stuff
}
}
It looks like you are intending to use ? like in TypeScript where it implies an optional value; but this is not the case in C#. In C#, The T? syntax is shorthand for Nullable<T>. The Nullable<T> struct has a constraint on T such T must also be a struct. System.String, is a class and not a struct, so it cannot be used with Nullable<T>.
The purpose of Nullable<T> is to contain a either a value of type T OR null, since struct based values cannot be null references themselves. All class based values can already contain null references, so it doesn't make sense to use them with Nullable<T>.
Try rewriting your code like this:
public int MyMethod(string RunDate = null)
{
string sql = string.Empty;
int rowsChanged = -1;
if (String.IsNullOrEmpty(RunDate))
{
//do stuff
}
}
It must be string? RunDate = null this line. You don't need to declare string as nullable type string? since string by itself is a reference type and thus defaults to null. It can simply be
public int MyMethod(string RunDate = null)
{
// rest of code
}
Quick answer, no.
Longer answer, not yet.
Right now, before C# 8 is released (well, as long as you're not using C# 8 preview that is), the ? symbol when used to specify nullable reference types, is a syntax error. Let's ignore C# 8 for the time being.
type? is translated to Nullable<type>, and the Nullable<T> struct is declared like this:
public struct Nullable<T> where T : struct
In other words, T cannot be string, so this, string?, is not legal. This is what is giving you the syntax error.
Until C# 8 is released, or you start using C# 8 Preview, there is nothing you can do, except remove the question mark.
What happens when C# 8 is released?
Well, type? for reference types will not translate to Nullable<T> but instead to T with knowledge about the nullability. For fields, properties, parameters, return types, basically anything that isn't a local variable, this will translate into a declaration with an attribute stating the nullability. For local variables the compiler will keep track of the nullability.
So in this case, string.IsNullOrEmpty will in fact work because the parameter will still fundamentally be a string, it will just be a string with the knowledge of nullability attached to it.
The ? operator is used to declare non-nullable types as nullable, and the compiler compiles them to be of type Nullable<T>.
The System.String is a reference type thus is nullable.
Remove the ? operator and things should work.

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

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

Can a DateTime be null? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
DateTime “null” value
is it possible to set datetime object to null?
DateTime is a value type, which, just like int and double, has no meaningful null value.
In VB.NET, you can write this:
Dim d As DateTime = Nothing
But all this does is to set d to the default DateTime value. In C# the equivalent code would be this:
DateTime d = default(DateTime);
...which is equivalent to DateTime.MinValue.
That said, there is the Nullable<T> type, which is used to provide a null value for any value type T. The shorthand for Nullable<DateTime> in C# is DateTime?.
DateTime? myDate = null;
The question mark will give you a nullable type. The one that can either be set to its native value or to null.
DateTime itself is a value type. It cannot be null.
No -- DateTime is a struct in C# and structs (value types) can not be null.
You can, however, use Nullable<DateTime>.
Nope, you cannot for DateTime is a value type.
You might want to look at Nullable<DateTime> though (or DateTime? in short)
No, its a structure not a class. Either make it a nullable type, e.g. System.DateTime? myValue; or use the System.DateTime.MinValue as a sentinel.
Normally DateTime cannot be null, since is a Value Type, but using the nullable operator introduced in C# 2, you can accomplish this

Why is there a questionmark on the private variable definition?

I am reading an article about the MVVP Pattern and how to implement it with WPF. In the source code there are multiple lines where I cannot figure out what the question marks in it stand for.
private DateTime? _value;
What does the ? mean in the definition? I tried to find it in the help from VS but failed.
It's a nullable value. Structs, by default, cannot be nullable, they must have a value, so in C# 2.0, the Nullable<T> type was introduced to the .NET Framework.
C# implements the Nullable<T> type with a piece of syntactic sugar, which places a question mark after the type name, thus making the previously non-nullable type, nullable.
That means the type is Nullable.
cannot be null
DateTime
DateTime dt = null; // Error: Cannot convert null to 'System.DateTime'
because it is a non-nullable value type
can be null
DateTime? / Nullable<DateTime>
DateTime? dt = null; // no problems
This is a nullable type, you can assign null to it
It means that the field is a Nullable<DateTime>, i.e. a DateTime that can be null
Private DateTime? _value - means that the _value is nullable. check out this link for a better explanation.
http://davidhayden.com/blog/dave/archive/2005/05/23/1047.aspx
Hope this helps.
Thanks,
Raja

Categories