167

Googling is only coming up with the keyword, but I stumbled across some code that says

MyVariable = default(MyObject);

and I am wondering what it means.

John Smith
  • 7,243
  • 6
  • 49
  • 61
NibblyPig
  • 51,118
  • 72
  • 200
  • 356

9 Answers9

224
  • For a reference-type, it returns null
  • For a value-type other than Nullable<T> it returns a zero-initialized value
  • For Nullable<T> it returns the empty (pseudo-null) value (actually, this is a re-statement of the second bullet, but it is worth making it explicit)

The biggest use of default(T) is in generics, and things like the Try... pattern:

bool TryGetValue(out T value) {
    if(NoDataIsAvailable) {
        value = default(T); // because I have to set it to *something*
        return false;
    }
    value = GetData();
    return true;
}

As it happens, I also use it in some code-generation, where it is a pain to initialize fields / variables - but if you know the type:

bool someField = default(bool);
int someOtherField = default(int);
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);
Jack Taylor
  • 5,588
  • 19
  • 35
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 3
    If I create `class Foo` with property `int n`. Can I "overload" `default` to make it set `n` to say `5` instead of `0`? – Pratik Deoghare Mar 12 '10 at 13:31
  • 5
    @The Machine Charmer: No. You can't overload `default`. – Jeff Yates Mar 12 '10 at 13:55
  • Isn't ```int foo = default(int);``` the same was ```int foo;```? Ie don't uninitialized ints default to having the same value as ```default(int)```? – Adam Parkin Jan 07 '15 at 22:08
  • 1
    @AdamParkin that depends on whether you are talking about fields vs locals; yes, fields initialize to a zero-d space, the same as `default(...)`; locals *do not have* default values (although technically, `.locals init` in IL means that they will again default to zero, but you need to use unsafe mechanisms to observe it) – Marc Gravell Jan 08 '15 at 07:56
  • "It returns the empty (psuedo-null) value that... that what? Looks like the sentence wasn't finished. –  May 05 '16 at 01:29
  • @Joshua tidies a little; I don't recall if I had anything extra I intended to write there – Marc Gravell May 05 '16 at 06:40
23

default keyword will return null for reference types and zero for numeric value types.

For structs, it will return each member of the struct initialized to zero or null depending on whether they are value or reference types.

from MSDN

Simple Sample code :<br>
    class Foo
    {
        public string Bar { get; set; }
    }

    struct Bar
    {
        public int FooBar { get; set; }
        public Foo BarFoo { get; set; }
    }

    public class AddPrinterConnection
    {
        public static void Main()
        {

            int n = default(int);
            Foo f = default(Foo);
            Bar b = default(Bar);

            Console.WriteLine(n);

            if (f == null) Console.WriteLine("f is null");

            Console.WriteLine("b.FooBar = {0}",b.FooBar);

            if (b.BarFoo == null) Console.WriteLine("b.BarFoo is null");

        }
    }

OUTPUT:

0
f is null
b.FooBar = 0
b.BarFoo is null
Pratik Deoghare
  • 35,497
  • 30
  • 100
  • 146
  • This [tutorial](https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/page?view=aspnetcore-7.0&tabs=visual-studio#the-create-delete-details-and-edit-pages) has this code `public IList Movie { get;set; } = default!;` I could not find this in [default value expressions](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default) nor [Default values of C# types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values). It seems there is no difference see [linqpad-demo](https://i.stack.imgur.com/mutgW.png) – surfmuggle Aug 30 '23 at 04:26
6

Specifies the default value of the type parameter.This will be null for reference types and zero for value types.

See default

rahul
  • 184,426
  • 49
  • 232
  • 263
5

Default value of MyObject. See default Keyword in Generic Code (C# Programming Guide) (MSDN):

In generic classes and methods, one issue that arises is how to assign a default value to a parameterized type T when you do not know the following in advance:

  • Whether T will be a reference type or a value type.
  • If T is a value type, whether it will be a numeric value or a struct.

Given a variable t of a parameterized type T, the statement t = null is only valid if T is a reference type and t = 0 will only work for numeric value types but not for structs. The solution is to use the default keyword, which will return null for reference types and zero for numeric value types. For structs, it will return each member of the struct initialized to zero or null depending on whether they are value or reference types. The following example from the GenericList class shows how to use the default keyword. For more information, see Generics Overview.

public class GenericList<T>
{
    private class Node
    {
        //...

        public Node Next;
        public T Data;
    }

    private Node head;

    //...

    public T GetNext()
    {
        T temp = default(T);

        Node current = head;
        if (current != null)
        {
            temp = current.Data;
            current = current.Next;
        }
        return temp;
    }
}
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
1

The default keyword returns the "default" or "empty" value for a variable of the requested type.

For all reference types (defined with class, delegate, etc), this is null. For value types (defined with struct, enum, etc) it's an all-zeroes value (for example, int 0, DateTime 0001-01-01 00:00:00, etc).

It's mostly used with generic code that can be applied to both reference and value types, because you can't assign null to a value type variable.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
0

It will set the default value of an object to a variable:

  • null for reference types and
  • 0 for value types.
surfmuggle
  • 5,527
  • 7
  • 48
  • 77
Webleeuw
  • 7,222
  • 33
  • 34
0

Perhaps this may help you:

using System;
using System.Collections.Generic;
namespace Wrox.ProCSharp.Generics
{
    public class DocumentManager < T >
    {
        private readonly Queue < T > documentQueue = new Queue < T > ();
        public void AddDocument(T doc)
        {
            lock (this)
            {
                documentQueue.Enqueue(doc);
            }
        }

        public bool IsDocumentAvailable
        {
            get { return documentQueue.Count > 0; }
        }
    }
}

It is not possible to assign null to generic types. The reason is that a generic type can also be instantiated as a value type, and null is allowed only with reference types. To circumvent this problem, you can use the default keyword. With the default keyword, null is assigned to reference types and 0 is assigned to value types.

public T GetDocument()
{
    T doc = default(T);
    lock (this)
    {
        doc = documentQueue.Dequeue();
    }
    return doc;
}

The default keyword has multiple meanings depending on the context where it is used. The switch statement uses a default for defining the default case, and with generics the default is used to initialize generic types either to null or 0 depending on if it is a reference or value type.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
perilbrain
  • 7,961
  • 2
  • 27
  • 35
  • In the `GetDocument()` example, it seems useless to initialize the local variable at the declaration, since this value is not used in any situation. Instead just do: `T doc; lock (this) { doc = documentQueue.Dequeue(); } return doc;` Of course, in a simple situation you can just return from inside the `lock`, like `lock (this) { return documentQueue.Dequeue(); }` By the way, many people prefer locking on a private field instead, since `this` is a reference which is available to other code. – Jeppe Stig Nielsen Oct 20 '21 at 11:45
0

When constraints have not been applied to restrict a generic type parameter to be a reference type, then a value type, such as a struct, could also be passed. In such cases, comparing the type parameter to null would always be false, because a struct can be empty, but never null

wrong code

public void TestChanges<T>(T inputValue)

            try
            {
                if (inputValue==null)
                    return;
                //operation on inputValue

           }
            catch
            {
                // ignore this.
            }
        }

corrected

public void TestChanges<T>(T inputValue)

            try
            {
                if (object.Equals(inputValue, default(T)) )
                    return;
                //operation on inputValue

           }
            catch
            {
                // ignore this.
            }
        }
Lijo
  • 6,498
  • 5
  • 49
  • 60
0

Another good use of default(T) is when compiler can't determine returning type, like in here

class X
{
    public int? P {get; set;}
}

// assigning in code

var x = new X();

// consider coll["key"] returns object boxed value
// data readers is one such case
x.P = myReader["someColumn"] == DbNull.Value ? default(int?) : (int)myReader["someColumn"];


T.S.
  • 18,195
  • 11
  • 58
  • 78
  • In such cases, `default(int?)` and `(int?)null` are equivalent, so it is a matter of taste which one you prefer. In newer C# versions, there is a third way, `(int?)default`, but I guess nobody will vote for that. – Jeppe Stig Nielsen Oct 20 '21 at 11:53
  • @JeppeStigNielsen Yea. My example might be not the most prolific. But it is more of an idea to use it for solving a compiler issues. – T.S. Oct 20 '21 at 14:46