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:
nullNullable<T> zwraca wartość zainicjowaną przez zeroNullable<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);
default.
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)?
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ć)
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.
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
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;
}
}
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.
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.
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.
}
}
class Fooz własnościąint n. Mogę „przeciążenie”default, aby ustawićnpowiedzieć5zamiast0?