Ответы:
nullNullable<T>него, возвращается значение с нулевой инициализациейNullable<T>он возвращает пустое (псевдо-нулевое) значение (на самом деле, это повторное утверждение первой пули, но его стоит сделать явным)Чаще всего используется default(T)в дженериках и таких вещах, как Try...шаблон:
bool TryGetValue(out T value) {
if(NoDataIsAvailable) {
value = default(T); // because I have to set it to *something*
return false;
}
value = GetData();
return true;
}
Как это бывает, я также использую его в некоторой генерации кода, где сложно инициализировать поля / переменные, но если вы знаете тип:
bool someField = default(bool);
int someOtherField = default(int)
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);
default.
int foo = default(int);было int foo;? Т.е. не инициализированные ints по умолчанию имеют то же значение, что и default(int)?
default(...); у местных жителей нет значений по умолчанию (хотя технически .locals initв IL означает, что они снова будут по умолчанию равны нулю, но вам нужно использовать небезопасные механизмы, чтобы наблюдать за этим)
defaultключевое слово вернется nullдля ссылочных типов иzero для числовых типов значений.
Для struct s он вернет каждый член структуры, инициализированный нулем или нулем, в зависимости от того, являются ли они типами значений или ссылочными типами.
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");
}
}
ВЫВОД:
0
f is null
b.FooBar = 0
b.BarFoo is null
Значение по умолчанию MyObject. См. Ключевое слово по умолчанию в универсальном коде (Руководство по программированию на C #) (MSDN):
В универсальных классах и методах возникает одна проблема: как присвоить значение по умолчанию параметризованному типу T, если вы заранее не знаете следующее:
- Будет ли T ссылочным типом или типом значения.
- Если T - тип значения, будет ли это числовое значение или структура.
Для переменной t параметризованного типа T оператор t = null действителен только в том случае, если T является ссылочным типом, а t = 0 будет работать только для числовых типов значений, но не для структур. Решение состоит в том, чтобы использовать ключевое слово по умолчанию, которое будет возвращать null для ссылочных типов и ноль для числовых типов значений. Для структур он вернет каждый элемент структуры, инициализированный нулем или нулем, в зависимости от того, являются ли они значениями или ссылочными типами. В следующем примере из класса GenericList показано, как использовать ключевое слово по умолчанию. Для получения дополнительной информации см. Обзор универсальных шаблонов.
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;
}
}
В defaultключевом слове возвращает « по умолчанию» или «пустое» значение для переменного запрашиваемого типа.
Для всех ссылочных типов (определенных с помощью class, delegateи т. Д.) Это null. Для типов значений (определенных с struct, enumи т.д.) , это значение всех нулей (например, int 0, DateTime 0001-01-01 00:00:00и т.д.).
В основном он используется с универсальным кодом, который может применяться как к ссылочным типам, так и к типам значений, поскольку вы не можете присвоить nullзначение переменной типа значения.
Возможно, это поможет вам:
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; }
}
}
}
Невозможно присвоить значение null универсальным типам. Причина в том, что универсальный тип также может быть создан как тип значения, а значение null допускается только со ссылочными типами. Чтобы обойти эту проблему, вы можете использовать ключевое слово по умолчанию. С ключевым словом default null присваивается ссылочным типам, а 0 присваивается типам значений.
public T GetDocument()
{
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
Ключевое слово по умолчанию имеет несколько значений в зависимости от контекста, в котором оно используется. Оператор switch использует значение по умолчанию для определения случая по умолчанию, а с универсальными типами значение по умолчанию используется для инициализации универсальных типов либо значением null, либо 0 в зависимости от того, является ли это типом ссылки или значением.
Если не были применены ограничения, чтобы ограничить параметр универсального типа ссылочным типом, то также можно передать тип значения, например структуру. В таких случаях сравнение параметра типа с null всегда будет ложным , потому что структура может быть пустой, но никогда не будет null.
неверный код
public void TestChanges<T>(T inputValue)
try
{
if (inputValue==null)
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
исправлено
public void TestChanges<T>(T inputValue)
try
{
if (object.Equals(inputValue, default(T)) )
return;
//operation on inputValue
}
catch
{
// ignore this.
}
}
class Fooс собственностьюint n. Могу ли я "перегрузить",defaultчтобы онnговорил5вместо0?