新的字符串类型

P.B*_*key 4 c#

来自Pro C#

参考"新的"内在数据类型......

所有内部数据类型都支持所谓的默认构造函数.它允许您使用new关键字创建变量.

[...]对象引用(包括字符串)设置为null.

在C#中,字符串没有公共默认构造函数.我的猜测是,由于字符串的不变性,它们有一个私有的默认构造函数.但是,这里的上下文是在使用时讨论对象引用和字符串的整体new.

因为一个人做不到

String myString = new String();

所以,

String a;

引用字符串不会产生"默认值".相反,访问a是一个编译器错误.

虽然

public class StringContainer
{
    public static string myString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以合法可访问的字符串结果(默认为null).这不使用new.它执行某种神奇的构造.

在现场发生了StringContainer什么?因为字符串中似乎没有新的默认构造函数,这是C#书中的错误吗?

Eri*_*ert 18

所有内部数据类型都支持所谓的默认构造函数.它允许您使用new关键字创建变量.

该陈述中有许多微妙的错误.

首先,没有"内在"数据类型; 也许这个术语是在书中的其他地方定义的?

其次,更准确地说所有结构类型都有一个名为"默认"构造函数的公共无参数构造函数.一些类型也有一个公共无参数ctor; 如果你不提供任何ctor,那么C#编译器将自动为你生成一个公共无参数ctor.如果您确实提供了ctor,那么C#编译器将不会为您执行此操作.

第三,构造函数不会创建变量.作者正在混淆一堆相关但不同的东西:"新"运算符,内存管理器,构造函数和变量,以及创建的对象.变量是存储位置,由CLR管理; 它们不是由"新"运算符创建的.

正确的说法是结构上的"new"运算符导致临时存储池上的CLR创建变量; 然后,该变量由内存管理器初始化,然后传递给构造函数以进行更多初始化.然后创建的值复制到其他位置.类上的"new"运算符导致CLR 在长期存储池上创建对象,然后将对该对象的引用传递给CLR.不需要涉及"变量".

将变量与对象混淆是一个非常常见的错误; 理解差异是很有价值的.

在C#中,字符串没有公共默认构造函数.

正确.

我的猜测是,由于字符串的不变性,它们有一个私有的默认构造函数.

好猜,但错了.字符串上没有私有的无参数构造函数.

[自动属性或字符串类型的字段]导致合法可访问的字符串(默认为null).这不使用新的.它执行某种神奇的构造.

它没有这样的事情.空引用根本不是构造对象.这是没有构造对象!

你基本上是说我的空车库里有一辆"神奇构造"的不存在的汽车.看一个空车库,这是一种非常奇怪的方式; 一个空车库根本没有车,不是一辆神奇的不存在的车.

StringContainer scenerio中发生了什么?

包含类型包含编译器生成的字段 - 变量 - 类型为字符串.我们假设包含类型是结构或类.当内存管理器初始化结构或类的存储时,内存管理器将空引用写入与该变量关联的存储位置.

最后:我怀疑你的困惑是因为你已经得到了"默认构造函数"并且"类型的默认值"混淆了.对于结构体,它们是相同的:

int x = new int();
Run Code Online (Sandbox Code Playgroud)

int x = default(int);
Run Code Online (Sandbox Code Playgroud)

两者都将int初始化为零.

对于一个班级,他们不会做同样的事情:

Fruit f = new Fruit(); 
Run Code Online (Sandbox Code Playgroud)

创建一个新的水果引用并为变量f指定引用,而:

Fruit f = default(Fruit);
Run Code Online (Sandbox Code Playgroud)

是相同的

Fruit f = null;
Run Code Online (Sandbox Code Playgroud)

没有调用构造函数.


Joe*_*ite 5

所有内部数据类型都支持所谓的默认构造函数.它允许您使用new关键字创建变量.

我不确定作者的"内在数据类型"是什么意思.我最好的猜测是他实际上意味着"值类型"(即用C#的struct关键字声明的类型),因为值类型总是有一个默认的构造函数,而引用类型可能不是.

因此,如果您有一个类型为struct类型的字段(例如Int32,CancellationToken),那么该字段将被初始化,就像调用类型的默认构造函数一样.

在实际应用中,有可能不是一个实际的类型的默认构造函数调用-内存只是初始化为全零,也就是如果你认为会发生同样的事情调用默认的构造函数.(这就是为什么你不能为值类型提供自己的无参数构造函数 - 无参数构造函数总是将内存初始化为全零.这大大简化了new int[10000]- 编译器实际上不需要调用new Int32()10,000次;它只是把内存归零.)

关于a中string字段的问题class与作者对"内部数据类型"的讨论并不真正相关,因为两者string和你的封闭class都是引用类型,而不是值类型.所以你的类不会有一个无参数构造函数 - 你不能覆盖; 它只有普通的构造函数.但是归零行为仍然存在:当你调用构造函数时,新的内存块在构造函数代码开始运行之前被清零.您的string字段是引用类型,零引用是null.