tags:

views:

570

answers:

7

Hi,

I'm wondering what ? means in C# ?
I'm seeing things like: DateTime? or int?. I suppose this is specific to C# 4.0?
I can't look for it in Google because I don't know the name of this thing.
The problem is I'm using DateTime and I have a lot of cast errors (from DateTime to DateTime?).

Thank you

+32  A: 

It's a shorthand for writing Nullable<int> or Nullable<DateTime>. Nullables are used with value types that cannot be null (they always have a value).

It is not specific to C#4 by the way.

You can only assign an int? to an int if it has a value, so your code would have to do things like:

int? n = 1;
int i = n ?? default(int); //or whatever makes sense

Also note that a Nullable has two properties, HasValue and Value that you can use test if a value has been set and to get the actual value.

klausbyskov
int i = n ?? default(int);
Brian Gideon
@Brian Gideon, you are totally right, I just wanted to illustrate that a Nullable has those two properties.
klausbyskov
@klausbyskov: It's fine to point out those properties, but you've given them in an example where they are a poor choice - maybe you could make a note of them separately and use `??` for the assignment to `int`.
280Z28
@280Z28 good point. I have done that.
klausbyskov
What if I wanted to make a class of mine Nullable? How can I do it? Is there any interface I need to implement?
Amokrane
A class instance is already able to be null. Nullable is used for structs, which cannot natively be null.
GalacticCowboy
good to know thanks!
Amokrane
@Amokrane you may want to read this: http://msdn.microsoft.com/en-us/library/34yytbws%28VS.71%29.aspx
klausbyskov
I'd add that `myNullableInt != null` is generally more readable than `myNullableInt.HasValue`, which is why they added it. Both compile to the same thing, but `!= null` is a more universally recognised check for non-null variables.
Keith
You can also use `n.GetValueOrDefault()` instead of `n ?? default(int)`
Greg
+12  A: 

It means it's a nullable type.

It allows you to assign a null value to value types such as int and DateTime. It's very helpful with things like optional fields in a database.

PatrickJ
+5  A: 

It designates nullable types.

I suppose this is C# specific to C# 4.0?

It has been in C# since 2.0

Kevin
+4  A: 

The ? is a nullable value type.

You can use the ?? operator to mix it with value types:

const int DefaultValue = -1;

// get a result that may be an integer, or may be null
int? myval = GetOptionalIdFromDB();

// the value after ?? is used if myval is null
int nonNullable = myval ?? DefaultValue;

The nullable type can be compared to null, so the above is shorthand for:

if( myval != null ) {
    nonNullable = myval.Value;
} else {
    nonNullable = DefaultValue;
}

But I prefer ??

Keith
+1  A: 

A gotcha to look out for: [edit: apparently this only happens sometimes]

// nullable type properties may not initialize as null
private int? foo; // foo = 0

// to be certain, tell them to be null
private int? foo = null;
Matt
That's not been my experience: Can you post a full repro with a main method and everything? Like this: static class Program { private static int? i; public static void Main() { Console.WriteLine(i); } }
Rob Fonseca-Ensor
Actually, you're right... when I do a straight up test in Snippet Compiler, it does initialize to null. When I've written code in a page code-behind, accessing properties from another public sealed class, I've seen them initialize as their value type defaults. I'll have to dig deeper to find out when/why that happens.-1 from myself!
Matt
A: 

It is a shorthand way of declaring an implementation of the generic class Nullable<T>, where T is a non-nullable value type.

So

int? i = null;

is the same as

Nullable<int> i = null;

As mentioned above Nullable<T> exposes the HasValue property so you can check if i has a value before working on it.

Interesting to note: If you cast Nullable<int> i = 3; to an object, you can cast back to an int or a Nullable<int> because it had a value before boxing. If, however you cast Nullable<int> i = null; to an object you will get a NullReferenceException when casting back to an int but you can cast back to a Nullable<int>.

Peter Kelly
A: 

As others have said, after the name of a type it means the nullable type.

? is also used in the condition operator.

int max = x > y ? x : y

This is equivalent to:

int max;
if( x > y )
{
  max = x;
}
else
{
  max = y;
}
Scott Langham