Що означає за замовчуванням (об'єкт); робити в C #?


133

Гуглінг придумує лише ключове слово, але я натрапив на якийсь код, який говорить

MyVariable = default(MyObject);

і мені цікаво, що це означає.

Відповіді:


189
  • Для довідкового типу він повертається null
  • Для типу типу, відмінного від значення, Nullable<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);

1
Якщо я створюю class Fooз власністю int n. Чи можу я "перевантажувати" так, defaultщоб він nміг говорити 5замість 0?
Pratik Deoghare

4
@ Машинна чарівниця: Ні. Ви не можете перевантажуватись default.
Джефф Йейтс

Чи не int foo = default(int);те ж саме було int foo;? Тобто не неініціалізовані вставки за замовчуванням мають те саме значення, що і default(int)?
Адам Паркін

1
@AdamParkin, що залежить від того, чи говориш ти про поля проти місцевих жителів; так, поля ініціалізуються на нульовий простір, те саме, що default(...); місцеві жителі не мають значень за замовчуванням (хоча технічно це .locals initв IL означає, що вони знову за замовчуванням, але вам потрібно використовувати небезпечні механізми, щоб спостерігати за цим)
Marc Gravell

"Він повертає порожнє (psuedo-null) значення, що ... що що? Схоже, речення не було закінчено.

14

defaultключове слово повернеться nullдля типів посилань та zeroдля типів числових значень.

Для structs він поверне кожному члену структури, ініціалізованому до нуля або нуля, залежно від того, чи є вони значеннями або еталонними типами.

від 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");

        }
    }

ВИХІД:

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

3

Значення за замовчуванням 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;
    }
}

2

Визначає значення за замовчуванням для параметра типу. Це буде нульовим для еталонних типів і нульовим для типів значень.

Див. За замовчуванням


1

У defaultключовому слові повертає « по умовчанням» або «порожній» значення для змінного запитуваної типу.

Для всіх типів еталонних (визначених за class, delegateі т.д.), це null. Для типів значень (визначених за struct, enumі т.д.) , це значення всіх нулів (наприклад, int 0, DateTime 0001-01-01 00:00:00і т.д.).

В основному використовується з загальним кодом, який можна застосувати як до посилань, так і до значень, оскільки ви не можете призначити nullзмінну типу значення.


0

Він встановить значення об'єкта за замовчуванням для змінної: null для посилальних типів та 0 для типів значень.


0

Можливо, це може допомогти вам:

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, залежно від того, чи є це посиланням або типом значення.


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.
            }
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.