4

I am using Eto gui framework. I saw some magic grammar in their source code; for example:

int x;
int? x;
void func(int param);
void func(int? param);

What's different? I am confused. and the symbol ? is hard to google.

amiry jd
  • 27,021
  • 30
  • 116
  • 215
afpro
  • 1,103
  • 7
  • 12
  • possible duplicate of [Why is there a questionmark on the private variable definition?](http://stackoverflow.com/questions/2326158/why-is-there-a-questionmark-on-the-private-variable-definition) – Shadow The GPT Wizard Feb 26 '13 at 07:45
  • possible duplicate of [C# - Basic question: What is '?'?](http://stackoverflow.com/questions/2699373/c-sharp-basic-question-what-is) – Soner Gönül Feb 28 '13 at 22:43

2 Answers2

9

It means they are Nullable, they can hold null values.

if you have defined:

int x;

then you can't do:

x = null; // this will be an error. 

but if you have defined x as:

int? x;

then you can do:

x = null; 

Nullable<T> Structure

In C# and Visual Basic, you mark a value type as nullable by using the ? notation after the value type. For example, int? in C# or Integer? in Visual Basic declares an integer value type that can be assigned null.

Personally I would use http://www.SymbolHound.com for searching with symbols, look at the result here

? is just syntactic sugar, its equivalent to:

int? x is same as Nullable<int> x

Habib
  • 219,104
  • 29
  • 407
  • 436
5

structs (like int, long, etc) cannot accept null by default. So, .NET provides a generic struct named Nullable<T> that the T type-param can be from any other structs.

public struct Nullable<T> where T : struct {}

It provides a bool HasValue property that indicates whether the current Nullable<T> object has a value; and a T Value property that gets the value of the current Nullable<T> value (if HasValue == true, otherwise it will throw an InvalidOperationException):

public struct Nullable<T> where T : struct {
    public bool HasValue {
        get { /* true if has a value, otherwise false */ }
    }
    public T Value {
        get {
            if(!HasValue)
                throw new InvalidOperationException();
            return /* returns the value */
        }
    }
}

And finally, in answer of your question, TypeName? is a shortcut of Nullable<TypeName>.

int? --> Nullable<int>
long? --> Nullable<long>
bool? --> Nullable<bool>
// and so on

and in usage:

int a = null; // exception. structs -value types- cannot be null
int? a = null; // no problem 

For example, we have a Table class that generates HTML <table> tag in a method named Write. See:

public class Table {

    private readonly int? _width;

    public Table() {
        _width = null;
        // actually, we don't need to set _width to null
        // but to learning purposes we did.
    }

    public Table(int width) {
        _width = width;
    }

    public void Write(OurSampleHtmlWriter writer) {
        writer.Write("<table");
        // We have to check if our Nullable<T> variable has value, before using it:
        if(_width.HasValue)
            // if _width has value, we'll write it as a html attribute in table tag
            writer.WriteFormat(" style=\"width: {0}px;\">");
        else
            // otherwise, we just close the table tag
            writer.Write(">");
        writer.Write("</table>");
    }
}

Usage of the above class -just as an example- is something like these:

var output = new OurSampleHtmlWriter(); // this is NOT a real class, just an example

var table1 = new Table();
table1.Write(output);

var table2 = new Table(500);
table2.Write(output);

And we will have:

// output1: <table></table>
// output2: <table style="width: 500px;"></table>
amiry jd
  • 27,021
  • 30
  • 116
  • 215
  • 1
    +1 but ..`value types and will be stored in stack ...` - Not really. See: [The Stack Is An Implementation Detail, Part One](http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx) By Eric Lippert – Habib Feb 26 '13 at 06:01