560

Typically the main use of the question mark is for the conditional, x ? "yes" : "no".

But I have seen another use for it but can't find an explanation of this use of the ? operator, for example.

public int? myProperty
{
   get;
   set;
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
GenEric35
  • 7,083
  • 3
  • 24
  • 25

9 Answers9

545

It means that the value type in question is a nullable type

Nullable types are instances of the System.Nullable struct. A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, a Nullable<Int32>, pronounced "Nullable of Int32," can be assigned any value from -2147483648 to 2147483647, or it can be assigned the null value. A Nullable<bool> can be assigned the values true, false, or null. The ability to assign null to numeric and Boolean types is especially useful when you are dealing with databases and other data types that contain elements that may not be assigned a value. For example, a Boolean field in a database can store the values true or false, or it may be undefined.

class NullableExample
{
  static void Main()
  {
      int? num = null;

      // Is the HasValue property true?
      if (num.HasValue)
      {
          System.Console.WriteLine("num = " + num.Value);
      }
      else
      {
          System.Console.WriteLine("num = Null");
      }

      // y is set to zero
      int y = num.GetValueOrDefault();

      // num.Value throws an InvalidOperationException if num.HasValue is false
      try
      {
          y = num.Value;
      }
      catch (System.InvalidOperationException e)
      {
          System.Console.WriteLine(e.Message);
      }
  }
}
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
Sean
  • 60,939
  • 11
  • 97
  • 136
  • 3
    Used for struct. Don't think it is actually useful for classes. – MonsieurDart Aug 05 '15 at 15:08
  • 10
    @MonsieurDart - thats why the answer says "value type" – Sean Aug 06 '15 at 12:06
  • Why does C# have this when most primitives already have a nullable type (Ex: int/Integer, double/Double, etc.)? – Antoine Dahan May 16 '16 at 12:41
  • 3
    @AntoineDahan - values types do not have nullable types as they are by definition non-nullable. I think you're thinking of Java where there is an `int` type and a corresponding `Integer` class, for example. – Sean May 16 '16 at 12:55
  • 2
    more recent (2015) documentation for nullable type [here](https://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.140).aspx) – dinosaur Aug 08 '16 at 21:56
  • 3
    Also note that [question mark can follow an object (instance of a type)](http://www.kunal-chowdhury.com/2014/12/csharp-6-null-conditional-operators.html#t6MtXHTTG6yPywQp.97) in c# 6 (VS 2015) – Carol Skelly Aug 23 '16 at 19:11
  • 1
    Found this to be very useful! I did have to implement it in mvc using ...(int? id = 0), so that I was able to call it with an empty parameter(). In my method, I had to code for both conditions. This saved me from having duplicate methods with overrides. – nocturns2 Sep 29 '16 at 10:26
  • *null* cannot be assigned to value types and primitive types, C# 2.0 introduced the mechanism *nullable type* so that value/primitive types can be assigned null. @ZimSystem, following question mark after reference **?.** type is very different operator called *null conditional operator*. It evaluates the expression to null if an instance is null (without throwing NullReferenceException). Consider old way *address = (emp.Address != null) ? emp.Address : null* => *address = emp?.Address* – A.B. May 03 '18 at 06:15
150

It is a shorthand for Nullable<int>. Nullable<T> is used to allow a value type to be set to null. Value types usually cannot be null.

z0r
  • 8,185
  • 4
  • 64
  • 83
Klaus Byskov Pedersen
  • 117,245
  • 29
  • 183
  • 222
  • 3
    The second sentence confuses me. What do you mean by "cannot"? On the compiler level or in the application context. – problemofficer - n.f. Monica Jun 29 '17 at 22:00
  • 6
    @problemofficer per definition, `value types` cannot be null. If you declare an int or a bool (which are value types) without specifically assigning a value, they would still have values (0 and false, respectively), ie. they would not be null. Unassigned `reference types`, such as object or MyClass, will, on the other hand, be null. You might want to read up on the difference between value types and reference types. – Klaus Byskov Pedersen Jun 30 '17 at 22:39
68

In

x ? "yes" : "no"

the ? declares an if sentence. Here: x represents the boolean condition; The part before the : is the then sentence and the part after is the else sentence.

In, for example,

int?

the ? declares a nullable type, and means that the type before it may have a null value.

Community
  • 1
  • 1
eKek0
  • 23,005
  • 25
  • 91
  • 119
  • 13
    I don't see any relationship between the '?' declaring a null-able type and a ternary expression. Voting your answer down sir. – Gus Crawford Mar 04 '15 at 15:38
  • 49
    I disagree with the comment above from Gus. The question shows that there is a possible confusion with the ternary expression. This answer addresses this issue. – Mario Levesque Jun 15 '15 at 15:04
  • Where would you use this kind of null-comparing? Inside a return it seems to not be allowed. `return value ? value : "isNull";` tells me that `string value` isnt convertable into bool. – C4d Sep 07 '15 at 13:20
  • 1
    I must say this is a very convoluted answer, especially when compared to others on this question.. -1 – FastTrack Feb 23 '17 at 22:37
  • 2
    The question states that it is NOT about the x ? "yes" : "no", but about when using question mark after a type declaration. This is a really bad answer in my opinion. – BerggreenDK Jun 18 '19 at 06:35
17

it declares that the type is nullable and you can use this without giving any value.

Thanos Papathanasiou
  • 904
  • 2
  • 12
  • 23
8

practical usage:

public string someFunctionThatMayBeCalledWithNullAndReturnsString(int? value)
{
  if (value == null)
  {
    return "bad value";
  }

  return someFunctionThatHandlesIntAndReturnsString(value);
}
A.J.Bauer
  • 2,803
  • 1
  • 26
  • 35
6

int? is shorthand for Nullable<int>. The two forms are interchangeable.

Nullable<T> is an operator that you can use with a value type T to make it accept null.

In case you don't know it: value types are types that accepts values as int, bool, char etc...

They can't accept references to values: they would generate a compile-time error if you assign them a null, as opposed to reference types, which can obviously accept it.

Why would you need that? Because sometimes your value type variables could receive null references returned by something that didn't work very well, like a missing or undefined variable returned from a database.

I suggest you to read the Microsoft Documentation because it covers the subject quite well.

Nicola Amadio
  • 149
  • 2
  • 11
  • if the two forms are interchangeable, how come one gives a compile-time error and the other doesn't? Compare `public Item? item { get; set; };` with `public Nullable item { get; set; };` where Item is some trivial class. – Mattias Martens Sep 07 '22 at 16:24
  • 1
    @MattiasMartens `Item` has to be a value type (a struct) - classes are reference types. [A nullable reference type is something quite different](https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references), unfortunately with identical syntax which causes some confusion. – Iain Nov 08 '22 at 23:01
6

Means that the variable declared with (int?) is nullable

int i1=1; //ok
int i2=null; //not ok

int? i3=1; //ok
int? i4=null; //ok
lucaspompeun
  • 170
  • 1
  • 9
2

To add on to the answers above, here is a code sample

struct Test
{
    int something;
}
struct NullableTest
{
    int something;
}
class Example
{
    public void Demo()
    {
        Test t = new Test();
        t = null;

        NullableTest? t2 = new NullableTest();
        t2 = null;
    }
}

This would give a compilation error:

Error 12 Cannot convert null to 'Test' because it is a non-nullable value type

Notice that there is no compilation error for NullableTest. (note the ? in the declaration of t2)

Sunil Purushothaman
  • 8,435
  • 1
  • 22
  • 20
2

To add on to the other answers:

Starting in C# 8.0, Nullable<> and ? are NOT always interchangeable. Nullable<> only works with Value types, whereas ? works with both Reference and Value types.

These can be seen here in the documentation

"A nullable reference type is noted using the same syntax as nullable value types: a ? is appended to the type of the variable."

And here

public struct Nullable<T> where T : struct

NullableMoh
  • 280
  • 3
  • 4