Cosa significa default (oggetto); fare in C #?


133

Google cerca solo la parola chiave, ma mi sono imbattuto in qualche codice che dice

MyVariable = default(MyObject);

e mi chiedo cosa significhi.

Risposte:


189
  • Per un tipo di riferimento, restituisce null
  • Per un tipo di valore diverso da quello Nullable<T>restituisce un valore inizializzato zero
  • Perché Nullable<T>restituisce il valore vuoto (pseudo-null) (in realtà, questa è una nuova dichiarazione del primo punto elenco, ma vale la pena renderlo esplicito)

Il più grande uso di default(T)è in generici e cose come lo Try...schema:

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

Come succede, lo uso anche in qualche generazione di codice, dove è un problema inizializzare campi / variabili - ma se conosci il tipo:

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

1
Se creo class Foocon proprietà int n. Posso "sovraccaricare" defaultper impostarlo nsu dire 5invece di 0?
Pratik Deoghare

4
@ The Machine Charmer: No. Non puoi sovraccaricare default.
Jeff Yates,

Non è stato int foo = default(int);lo stesso int foo;? Vale a dire che gli ints non inizializzati hanno lo stesso valore di default(int)?
Adam Parkin,

1
@AdamParkin dipende dal fatto che tu parli di campi vs gente del posto; sì, i campi vengono inizializzati su uno spazio zero-d, lo stesso di default(...); i locali non hanno valori predefiniti (anche se tecnicamente, .locals initin IL significa che torneranno di default a zero, ma è necessario utilizzare meccanismi non sicuri per osservarlo)
Marc Gravell

"Restituisce il valore vuoto (psuedo-null) che ... che cosa? Sembra che la frase non sia stata completata.

14

defaultla parola chiave restituirà nullper i tipi di riferimento e zeroper i tipi di valore numerici.

Per structs, restituirà ogni membro della struttura inizializzato su zero o null a seconda che siano tipi di valore o di riferimento.

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

        }
    }

PRODUZIONE:

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

3

Valore predefinito di MyObject. Vedi la parola chiave predefinita nel codice generico (Guida per programmatori C #) (MSDN):

Nelle classi e nei metodi generici, sorge un problema: come assegnare un valore predefinito a un tipo T parametrizzato quando non si conosce in anticipo quanto segue:

  • Se T sarà un tipo di riferimento o un tipo di valore.
  • Se T è un tipo di valore, se sarà un valore numerico o una struttura.

Data una variabile t di un tipo T parametrizzato, l'istruzione t = null è valida solo se T è un tipo di riferimento e t = 0 funziona solo per i tipi di valore numerici ma non per le strutture. La soluzione è utilizzare la parola chiave predefinita, che restituirà null per i tipi di riferimento e zero per i tipi di valore numerici. Per le strutture, restituirà ogni membro della struttura inizializzato su zero o null a seconda che si tratti di valori o tipi di riferimento. L'esempio seguente della classe GenericList mostra come utilizzare la parola chiave predefinita. Per ulteriori informazioni, vedere Panoramica di Generics.

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

Specifica il valore predefinito del parametro type, che sarà nullo per i tipi di riferimento e zero per i tipi di valore.

Vedi predefinito


1

La defaultparola chiave restituisce il valore "predefinito" o "vuoto" per una variabile del tipo richiesto.

Per tutti i tipi di riferimento (fissato con class, delegateecc), questo è null. Per i tipi di valore (definiti con struct, enum, ecc) è un valore di tutti-zeri (ad esempio, int 0, DateTime 0001-01-01 00:00:00, ecc).

Viene utilizzato principalmente con codice generico che può essere applicato a tipi di riferimento e di valore, poiché non è possibile assegnare nulla una variabile del tipo di valore.


0

Imposterà il valore predefinito di un oggetto su una variabile: null per i tipi di riferimento e 0 per i tipi di valore.


0

Forse questo può aiutarti:

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

Non è possibile assegnare null a tipi generici. Il motivo è che un tipo generico può anche essere istanziato come tipo valore e null è consentito solo con tipi di riferimento. Per aggirare questo problema, è possibile utilizzare la parola chiave predefinita. Con la parola chiave predefinita, null viene assegnato ai tipi di riferimento e 0 ai tipi di valore.

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

La parola chiave predefinita ha più significati a seconda del contesto in cui viene utilizzata. L'istruzione switch utilizza un valore predefinito per la definizione del caso predefinito e, con generici, il valore predefinito viene utilizzato per inizializzare i tipi generici su null o 0 a seconda che si tratti di un riferimento o di un tipo di valore.


0

Quando non sono stati applicati vincoli per limitare un parametro di tipo generico come tipo di riferimento, è possibile passare anche un tipo di valore, come una struttura. In questi casi, confrontare il parametro type con null sarebbe sempre falso , poiché una struttura può essere vuota, ma mai nulla

codice errato

public void TestChanges<T>(T inputValue)

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

           }
            catch
            {
                // ignore this.
            }
        }

corretto

public void TestChanges<T>(T inputValue)

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

           }
            catch
            {
                // ignore this.
            }
        }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.