Гуглінг придумує лише ключове слово, але я натрапив на якийсь код, який говорить
MyVariable = default(MyObject);
і мені цікаво, що це означає.
Гуглінг придумує лише ключове слово, але я натрапив на якийсь код, який говорить
MyVariable = default(MyObject);
і мені цікаво, що це означає.
Відповіді:
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;? Тобто не неініціалізовані вставки за замовчуванням мають те саме значення, що і default(int)?
default(...); місцеві жителі не мають значень за замовчуванням (хоча технічно це .locals initв IL означає, що вони знову за замовчуванням, але вам потрібно використовувати небезпечні механізми, щоб спостерігати за цим)
defaultключове слово повернеться nullдля типів посилань та zeroдля типів числових значень.
Для structs він поверне кожному члену структури, ініціалізованому до нуля або нуля, залежно від того, чи є вони значеннями або еталонними типами.
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 буде працювати лише для типів числових значень, але не для структур. Рішення полягає у використанні ключового слова за замовчуванням, яке поверне нуль для типів посилань і нуль для типів числового значення. Для структур він повертає кожного члена структури, ініціалізованого до нуля або нуля, залежно від того, чи є вони значеннями або еталонними типами. Наступний приклад з класу 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; }
}
}
}
Неможливо присвоїти нуль загальним типам. Причина полягає в тому, що загальний тип може бути ідентифікований як тип значення, а нульовий дозволений лише для типів посилань. Щоб обійти цю проблему, ви можете використовувати ключове слово за замовчуванням. За ключовим словом за замовчуванням нуль призначається типам посилань, а 0 - значенням типів.
public T GetDocument()
{
T doc = default(T);
lock (this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
Ключове слово за замовчуванням має кілька значень, залежно від контексту, де воно використовується. Оператор перемикання використовує за замовчуванням для визначення випадку за замовчуванням, а з дженериками типовий параметр використовується для ініціалізації загальних типів або до нуля, або 0, залежно від того, чи є це посиланням або типом значення.
Коли обмеження не застосовуються для обмеження параметру загального типу, який є еталонним типом, тоді також може бути переданий тип значення, такий як структура. У таких випадках порівняння параметра типу з 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?