Respuestas:
nullNullable<T>que devuelve un valor inicializado ceroNullable<T>devuelve el valor vacío (pseudo-nulo) (en realidad, esta es una nueva declaración de la primera viñeta, pero vale la pena hacerlo explícito)El mayor uso de default(T)es en genéricos, y cosas como el Try...patrón:
bool TryGetValue(out T value) {
if(NoDataIsAvailable) {
value = default(T); // because I have to set it to *something*
return false;
}
value = GetData();
return true;
}
Como sucede, también lo uso en algunos generación de código, donde es difícil inicializar campos / variables, pero si conoce el tipo:
bool someField = default(bool);
int someOtherField = default(int)
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);
default.
int foo = default(int);mismo int foo;? Es decir, ¿los ints no inicializados tienen el mismo valor que default(int)?
default(...); los locales no tienen valores predeterminados (aunque técnicamente, .locals initen IL significa que volverán a ser predeterminados a cero, pero debe usar mecanismos inseguros para observarlo)
defaultla palabra clave devolverá nullpara los tipos de referencia y zeropara los tipos de valores numéricos.
Para structs, devolverá a cada miembro de la estructura inicializada a cero o nulo, dependiendo de si son valores o tipos de referencia.
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");
}
}
SALIDA:
0
f is null
b.FooBar = 0
b.BarFoo is null
Valor predeterminado de MyObject. Consulte la palabra clave predeterminada en el Código genérico (Guía de programación de C #) (MSDN):
En las clases y métodos genéricos, un problema que surge es cómo asignar un valor predeterminado a un tipo T parametrizado cuando no conoce de antemano lo siguiente:
- Si T será un tipo de referencia o un tipo de valor.
- Si T es un tipo de valor, ya sea un valor numérico o una estructura.
Dada una variable t de un tipo T parametrizado, la declaración t = nulo solo es válida si T es un tipo de referencia y t = 0 solo funcionará para tipos de valores numéricos pero no para estructuras. La solución es usar la palabra clave predeterminada, que devolverá nulo para los tipos de referencia y cero para los tipos de valor numérico. Para las estructuras, devolverá cada miembro de la estructura inicializado a cero o nulo, dependiendo de si son tipos de valor o de referencia. El siguiente ejemplo de la clase GenericList muestra cómo usar la palabra clave predeterminada. Para obtener más información, consulte Descripción general de genéricos.
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;
}
}
Especifica el valor predeterminado del parámetro de tipo. Esto será nulo para los tipos de referencia y cero para los tipos de valor.
Ver predeterminado
los default palabra clave devuelve el valor "predeterminado" o "vacío" para una variable del tipo solicitado.
Para todos los tipos de referencia (definidas con class, delegate, etc.), esto es null. Para los tipos de valor (definidos con struct, enum, etc.) que es un valor de todos-ceros (por ejemplo, int 0,DateTime 0001-01-01 00:00:00 , etc.).
Se usa principalmente con código genérico que se puede aplicar a los tipos de referencia y de valor, porque no se puede asignar nulla una variable de tipo de valor.
Quizás esto pueda ayudarte:
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; }
}
}
}
No es posible asignar nulos a tipos genéricos. La razón es que un tipo genérico también se puede instanciar como un tipo de valor, y nulo solo se permite con tipos de referencia. Para evitar este problema, puede usar la palabra clave predeterminada. Con la palabra clave predeterminada, se asigna nulo a los tipos de referencia y 0 a los tipos de valor.
public T GetDocument()
{
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
La palabra clave predeterminada tiene múltiples significados según el contexto donde se usa. La instrucción switch usa un valor predeterminado para definir el caso predeterminado, y con los genéricos, el valor predeterminado se usa para inicializar tipos genéricos ya sea nulo o 0, dependiendo de si es un tipo de referencia o valor.
Cuando no se han aplicado restricciones para restringir un parámetro de tipo genérico para que sea un tipo de referencia, también se podría pasar un tipo de valor, como una estructura. En tales casos, comparar el parámetro de tipo con nulo siempre sería falso , porque una estructura puede estar vacía, pero nunca nula
codigo erroneo
public void TestChanges<T>(T inputValue)
try
{
if (inputValue==null)
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
corregido
public void TestChanges<T>(T inputValue)
try
{
if (object.Equals(inputValue, default(T)) )
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
class Foocon propiedadint n. ¿Puedo "sobrecargar"defaultpara configurarlonpara que diga en5lugar de0?