什么是default(object); 用C#做?


133

谷歌搜索只提出了关键字,但我偶然发现了一些代码

MyVariable = default(MyObject);

我想知道这是什么意思。

Answers:


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用property 创建int n。我可以“超载” default以设置n5代替0吗?
Pratik Deoghare 2010年

4
@The Machine Charmer:不,你不能超载default
杰夫·耶茨

是不是int foo = default(int);一样int foo;?即,未初始化的int是否默认具有与default(int)?相同的值?
亚当·帕金

1
@AdamParkin取决于您是在谈论田野还是当地人;是的,字段初始化为零维空间,与default(...); 相同。当地人没有默认值(尽管从技术上讲,.locals initIL中的默认值意味着它们将再次默认为零,但您需要使用不安全的机制进行观察)
Marc Gravell

“它返回一个空的(伪空)值……那是什么?看起来句子还没有结束

14

default关键字将返回null引用类型和zero数值类型。

对于structs,它将返回初始化为零或null的结构的每个成员,具体取决于它们是值类型还是引用类型。

从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,对于数值类型,将返回零。对于结构,它将返回初始化为零或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

指定type参数的默认值,对于引用类型为null,对于值类型为0。

查看默认


1

default关键字返回“默认”或“空”值用于所请求的类型的变量。

对于所有的引用类型(具有限定的classdelegate等),这是null。对于值类型(与定义structenum等)这是一个全零值(例如,int 0DateTime 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。要避免此问题,可以使用默认关键字。使用默认关键字时,将null分配给引用类型,将0分配给值类型。

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

默认关键字具有多种含义,具体取决于使用它的上下文。switch语句使用默认值定义默认情况,对于泛型,默认值用于将泛型类型初始化为null或0,具体取决于它是引用类型还是值类型。


0

如果尚未应用约束将通用类型参数限制为引用类型,则还可以传递值类型(例如struct)。在这种情况下,将type参数与null进行比较将始终为false因为结构可以为空,但不能为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.
            }
        }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.