Co oznacza default (obiekt); zrobić w C #?


136

Googling wymyśla tylko słowo kluczowe, ale natknąłem się na kod, który mówi

MyVariable = default(MyObject);

i zastanawiam się, co to znaczy.

Odpowiedzi:


190
  • W przypadku typu referencyjnego zwraca null
  • Dla typu wartości innego niż Nullable<T> zwraca wartość zainicjowaną przez zero
  • Ponieważ Nullable<T>zwraca pustą (pseudo-zerową) wartość (w rzeczywistości jest to ponowne wyrażenie pierwszego punktu, ale warto to wyraźnie zaznaczyć)

Największe zastosowanie default(T)znajduje się w rodzajach ogólnych i rzeczach takich jak Try...wzorzec:

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

Tak się składa, że ​​używam go również przy generowaniu kodu, gdzie uciążliwe jest inicjowanie pól / zmiennych - ale jeśli znasz typ:

bool someField = default(bool);
int someOtherField = default(int)
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);

1
Jeśli tworzę class Fooz własnością int n. Mogę „przeciążenie” default, aby ustawić npowiedzieć 5zamiast 0?
— Pratik Deoghare

4
@ The Machine Charmer: Nie. Nie możesz przeciążać default.
— Jeff Yates,

Czy to nie int foo = default(int);to samo było int foo;? Tzn. Nie zainicjowane wartości int mają domyślnie taką samą wartość jak default(int)?
— Adam Parkin

1
@AdamParkin to zależy od tego, czy mówisz o polach, czy o miejscowych; tak, pola są inicjalizowane w spacji zero-d, tak samo jak default(...); locals nie mają wartości domyślnych (chociaż technicznie .locals initw IL oznacza to, że znowu będą ustawione na zero, ale musisz użyć niebezpiecznych mechanizmów, aby to przestrzegać)
— Marc Gravell

„Zwraca pustą (psuedo-null) wartość, która ... to co? Wygląda na to, że zdanie nie jest zakończone.

16

defaultsłowo kluczowe zwróci nulldla typów referencyjnych i zeroliczbowych typów wartości.

Dla structs zwróci każdy element członkowski struktury zainicjowany do zera lub null w zależności od tego, czy są to typy wartości, czy odwołania.

z 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");

        }
    }

WYNIK:

0
f is null
b.FooBar = 0
b.BarFoo is null

3

Wartość domyślna MyObject. Zobacz domyślne słowo kluczowe w kodzie ogólnym (przewodnik programowania C #) (MSDN):

W klasach i metodach generycznych jednym problemem, który się pojawia, jest przypisanie wartości domyślnej sparametryzowanemu typowi T, gdy nie znasz z góry następujących elementów:

  • Czy T będzie typem referencyjnym czy typem wartości.
  • Jeśli T jest typem wartości, czy będzie to wartość liczbowa, czy struktura.

Biorąc pod uwagę zmienną t sparametryzowanego typu T, instrukcja t = null jest poprawna tylko wtedy, gdy T jest typem referencyjnym, a t = 0 będzie działać tylko dla liczbowych typów wartości, ale nie dla struktur. Rozwiązaniem jest użycie domyślnego słowa kluczowego, które zwróci wartość null dla typów referencyjnych i zero dla typów wartości liczbowych. W przypadku struktur zwróci każdy element członkowski struktury zainicjowany na zero lub null w zależności od tego, czy są to typy wartości, czy odwołania. Poniższy przykład z klasy GenericList pokazuje, jak używać domyślnego słowa kluczowego. Aby uzyskać więcej informacji, zobacz Omówienie typów ogólnych.

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;
    }
}

2

Określa domyślną wartość parametru typu, która będzie miała wartość null dla typów referencyjnych i zero dla typów wartości.

Zobacz domyślne


1

Te defaultpowroty słów kluczowych „default” lub „pusty” wartość dla zmiennej żądanego typu.

W przypadku wszystkich typów odniesienia (określonych z class, delegateitp), to jest null. Dla określonych rodzajów wartości (z struct, enumitp) jest wartością wszystkich-zera (na przykład int 0, DateTime 0001-01-01 00:00:00itp).

Jest najczęściej używany z kodem ogólnym, który można zastosować zarówno do typów referencyjnych, jak i wartościowych, ponieważ nie można przypisać nulldo zmiennej typu wartości.


0

Ustawi domyślną wartość obiektu na zmienną: null dla typów referencyjnych i 0 dla typów wartości.


0

Być może może ci to pomóc:

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; }
        }
    }
}

Nie jest możliwe przypisanie wartości null do typów ogólnych. Powodem jest to, że typ ogólny można również utworzyć jako typ wartości, a wartość null jest dozwolona tylko w przypadku typów referencyjnych. Aby obejść ten problem, możesz użyć domyślnego słowa kluczowego. Z domyślnym słowem kluczowym, null jest przypisywane do typów odwołań, a 0 jest przypisywane do typów wartości.

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

Domyślne słowo kluczowe ma wiele znaczeń w zależności od kontekstu, w którym jest używane. Instrukcja switch używa wartości domyślnej do definiowania przypadku domyślnego, aw przypadku typów ogólnych wartość domyślna jest używana do inicjowania typów ogólnych na wartość null lub 0, w zależności od tego, czy jest to odwołanie, czy typ wartości.


0

Gdy ograniczenia nie zostały zastosowane w celu ograniczenia parametru typu ogólnego do typu referencyjnego, można również przekazać typ wartości, taki jak struktura. W takich przypadkach porównanie parametru typu z wartością null zawsze będzie fałszywe , ponieważ struktura może być pusta, ale nigdy nie ma wartości null

niepoprawny kod

public void TestChanges<T>(T inputValue)

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

           }
            catch
            {
                // ignore this.
            }
        }

poprawione

public void TestChanges<T>(T inputValue)

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

           }
            catch
            {
                // ignore this.
            }
        }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.