随笔 - 139  文章 - 0  评论 - 421  阅读 - 17万

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

大家看一个结构体定义:

    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;

posted on   周雪峰  阅读(1700)  评论(12编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
< 2009年12月 >
29 30 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2
3 4 5 6 7 8 9

点击右上角即可分享
微信分享提示