Что значит default (объект); делать в C #?


133

В Google только появляется ключевое слово, но я наткнулся на код, который говорит

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;? Т.е. не инициализированные ints по умолчанию имеют то же значение, что и default(int)?
— Адам Паркин

1
@AdamParkin, который зависит от того, говорите ли вы о полях или о местных; да, поля инициализируются пробелом с нулевым d, так же, как default(...); у местных жителей нет значений по умолчанию (хотя технически .locals initв IL означает, что они снова будут по умолчанию равны нулю, но вам нужно использовать небезопасные механизмы, чтобы наблюдать за этим)
— Марк Гравелл

«Он возвращает пустое (psuedo-null) значение, которое ... это что? Похоже, предложение не закончено.

14

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

Для struct s он вернет каждый член структуры, инициализированный нулем или нулем, в зависимости от того, являются ли они типами значений или ссылочными типами.

из 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 будет работать только для числовых типов значений, но не для структур. Решение состоит в том, чтобы использовать ключевое слово по умолчанию, которое будет возвращать 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;
    }
}

2

Задает значение по умолчанию для параметра типа. Это будет null для ссылочных типов и ноль для типов значений.

По умолчанию


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; }
        }
    }
}

Невозможно присвоить значение null универсальным типам. Причина в том, что универсальный тип также может быть создан как тип значения, а значение null допускается только со ссылочными типами. Чтобы обойти эту проблему, вы можете использовать ключевое слово по умолчанию. С ключевым словом default null присваивается ссылочным типам, а 0 присваивается типам значений.

public T GetDocument()
{
    T doc = default(T);
    lock (this)
    {
        doc = documentQueue.Dequeue();
    }
    return doc;
}

Ключевое слово по умолчанию имеет несколько значений в зависимости от контекста, в котором оно используется. Оператор switch использует значение по умолчанию для определения случая по умолчанию, а с универсальными типами значение по умолчанию используется для инициализации универсальных типов либо значением null, либо 0 в зависимости от того, является ли это типом ссылки или значением.


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.
            }
        }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.