深入解析值类型的初始化过程!

大家看一个结构体定义:

    struct Book
    {
        public string author;
        public Book(string author)
        {
            this.author = author;
        }

        public string Author
        {
            get { return author; }
            set { author = value; }
        } 

    } 

下面是初始化代码:

        static void Main(string[] args)
        {
            Book b;
            b.author = "asdf";           
        } 

这段代码可以通过编译,当然如果把struct换成class,马上就会发生编译错误了:使用了未赋值的局部变量b.

为什么struct变量可以不通过Book b=new Book()的方式而使用字段呢?

     大师Jeffery在他的书中解释了类似的现象,实际上对于struct来说:
     Book b;
     Book b=new Book();
     在本质上这两行代码没有区别,都会把实例分配在线程堆栈上,并产生把所有字段置0(二进制意义上的0)的IL指令,但是为什么通过Book b;这样的方式来初始化,以后访问其他成员会导致编译错误呢?

比如:b.Author="asdf";//这里访问属性Author,会发生编译错误

原因是C#编译器“认为”设置public字段是初始化行为,而设置属性不是初始化行为,的编译检查,你通过Book b=new Book();来初始化会让编译器认为b已经初始化了!

大家可能认为Book b=new Book();会调用Book的默认无参构造函数,实际上并非如此,对于struct来说,C#编译器并不会像引用类型那样产生默认的无参构造函数,而且为了避免混淆,也不允许我们自己为struct定义无参构造函数! 

作为一种良好的编程习惯,也为了避免不必要的误解,还是建议直接使用Book b=new Book();这样的方式来初始化struct变量!

对于其他值类型,C#给我们提供了更简单的初始化语法,比如:

int i=0;

原文地址:https://www.cnblogs.com/xuefeng1982/p/1618251.html