77

我看到一些代码会返回默认值,所以我想知道对于用户定义的类,编译器将如何定义其默认值?

4

10 回答 10

87

为了配合其余部分,它将是null,但我还应该补充一点,您可以获得任何类型的默认值,使用default

default(MyClass) // null
default(int) // 0

它在使用泛型时特别有用;default(T)如果您的返回类型是T并且您不想假设它可以为空,您可能想要返回。

于 2009-12-17T07:58:10.737 回答
18

class的默认值为null

于 2009-12-17T07:55:12.987 回答
17

注意:ADefaultValueAttribute不会导致成员使用属性值自动初始化。您必须在代码中设置初始值。

您可以使用DefaultValueAttribute.

private bool myVal = false;

[DefaultValue(false)]
public bool MyProperty
{
    get
    {
       return myVal;
    }
    set
    {
       myVal = value;
    }
 }

我知道这不能回答您的问题,只是想将其添加为相关信息。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

于 2009-12-17T07:58:47.757 回答
9

类的默认值为null. 对于结构体,默认值与实例化结构体的默认无参数构造函数时得到的值相同(顺便说一下不能覆盖)。相同的规则递归地应用于类或结构中包含的所有字段。

于 2009-12-17T08:00:33.303 回答
9

我会让这个“默认”类实例成为一个字段而不是属性,就像System.String.Empty看起来一样:

public class Person 
{
    public string Name { get; set; }
    public string Address { get; set; }

    public static readonly Person Default = new Person() 
    {
        Name = "Some Name",
        Address = "Some Address"
    };
}

...

public static void Main(string[] args)
{
    string address = String.Empty;

    Person person = Person.Default;

    //the rest of your code
}
于 2016-08-25T07:25:07.750 回答
6

如果您想知道为什么没有允许您以某种方式为类定义非空默认值的语言功能,请记住类是“引用类型”。引用类型是对已分配内存的引用,或者换句话说,除了 null 之外的任何内容都是需要分配内存的该对象的构造实例。所以现在考虑如何将“default”关键字集成到 .NET 中以便它适用于类,想象一下可以考虑的两种实现:

  1. 您可以定义一个标记为默认值的静态实例。也许“默认”变得像一个访问修饰符(例如公共默认只读等)。这可能行得通,也许。但它真的是一个有价值的语言特性吗?至少这样,每个“默认”都会指向同一个静态内存实例。

  2. 如果每次在类上使用 default 关键字时都会调用默认构造函数怎么办?这会很糟糕,因为如果您没有覆盖 Equals 以不比较引用,两个默认值可能彼此不相等,而且由于内存管理和内存分配性能受到影响,以及构造函数的副作用也很糟糕。

所以总而言之,我认为这是我们真正不想要的语言特性。并且 default(MyClass) 将始终 == null。

于 2015-04-03T15:01:30.520 回答
5

如果是引用类型,则默认值为null,如果是值类型,则视情况而定。

于 2009-12-17T07:55:31.583 回答
3
Assert.IsTrue(default(MyClass) == null);
于 2009-12-17T07:58:33.547 回答
1

对于引用类型或可为空的值类型,默认值为null

Person person = default; // = null
IEnumerable<Person> people = default; // = null
int? value = default; // = null

对于值类型,它取决于它是哪种值类型:

int value = default; // = 0
DateTime dateTime = default; // = 1/1/0001 12:00:00 AM
Guid id = default; // = 00000000-0000-0000-0000-000000000000
于 2021-06-25T21:34:28.537 回答
0

希望能节省一些其他人的时间。

现在明显的选择(为此我仍然不得不在谷歌上搜索一下,因为首先登陆了这个主题)是编写一个扩展,它可以帮助你初始化一个类,不管它本身的复杂性(比如构造函数 getter/setter,它会阻止简单默认值直接赋值)。

稍微修改一下之前的答案:

public class Person 
{
    public string Name { get; set; }
    public string Address { get; set; }

    public static readonly Person Default = new Person() 
    {
        Name = "Some Name",
        Address = "Some Address"
    };
}

=>

public class Person 
{
    public string Name { get; set; }
    public string Address { get; set; }
}
public static class PersonExtentions
{
    public static Person withDefaults(this Person obj) {
      obj.Name = "John Doe";
      return obj;
    }
}

进而

Person x = new Person.withDefaults();
于 2022-01-14T05:37:30.603 回答