C # 中用户定义类的默认值

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

92461 次浏览

class的默认值是 null

如果是引用类型,则默认值为 null,如果是值类型,则取决于。

为了与其他的一起使用,它将是 null,但是我还要补充的是,您可以使用 default获得任何类型的默认值

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

它在处理泛型时特别有用; 如果返回类型是 T,并且不想假设它可以为空,那么可能需要返回 default(T)

Assert.IsTrue(default(MyClass) == null);

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

您可以使用 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

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

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

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

  2. 如果每次在类中使用 default 关键字时都调用这个缺省构造函数会怎么样?这将非常糟糕,因为如果不覆盖 Equals 以避免比较引用,那么两个默认值可能会相互不等,而且由于内存管理和内存分配性能受到影响,以及构造函数的副作用,这也会非常糟糕。

所以总的来说,我认为这是一个我们不想要的语言特征。而 default (MyClass)将始终 = = null。

我将这个“默认”类实例设置为字段而不是属性,就像 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
}

对于引用类型或可空值类型,默认值为 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

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

现在显而易见的选择(在这个话题之前,我还需要在谷歌上搜索一下)是编写一个扩展,帮助你初始化一个类,不管它本身有多复杂(比如构造函数 getters/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();