C#100问--为什么值类型不允许定义无参构造函数?

2024-01-13 07:58

本文主要是介绍C#100问--为什么值类型不允许定义无参构造函数?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

直接回答:
为了防止开发人员对这种构造器在什么时候调用产生迷惑,导致发生影响程序性能的问题,所以干脆禁止。

详细解答:
首先CLR是允许这种行为的,只是C#编译器不允许。
当程序new一个无参的值类型时,会分配一片内存(该片内存是已经分配过的),并将这片内存的脏数据(之前存储了一些其他数据)清理掉,即zeroed,这个工作是CLR调用IL形式的initobj指令完成的。当程序new一个无参的值类型时,new操作符就被编译成initobj指令。

考虑到有些情况会使用无参构造函数,而有些情况不能使用,容易造成困惑,破坏了一致性,所以干脆禁止。比如以下这个例子:

Struct[] foo = new Struct[1000];

对于上面这个语句,CLR可以通过分配内存并zeroed化内存的方式高效完成。但如果定义了无参构造函数的话,也就意味着要执行1000次无参构造函数,极其低效。


延申问题:在struct中定义一个值类型并赋值,则会发生什么?
会编译报错:结构中不能有实例字段初始值设定项。
原因就是C#不允许为值类型定义无参构造函数,所以不会自动执行内联初始化,所以不能在值类型中内联实例字段的初始化,他们总是被初始化为0或null。

struct SomeValType
{// 不能在值类型中内联实例字段的初始化private int m_x = 5;
}

延申知识点:
值类型若要显示定义有参构造函数,则必须对所有字段显示赋值

struct SomeValType
{private int m_x;private int m_y;public SomeValType(int x, int y){m_x = x;m_y = y;}
}

或者用这种方式

struct SomeValType
{private int m_x;private int m_y;public SomeValType(int x, int y){// 会将所有字段全部赋值为0this = new SomeValType();// 用x覆盖m_x的0m_x = x;   }
}

替代方案中用到的this在值类型中,this可赋值,因为它是一个实例。
而引用类型中,this只读不可赋值。

这篇关于C#100问--为什么值类型不允许定义无参构造函数?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600743

相关文章

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

C# Where 泛型约束的实现

《C#Where泛型约束的实现》本文主要介绍了C#Where泛型约束的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用的对象约束分类where T : structwhere T : classwhere T : ne

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

C#中DrawCurve的用法小结

《C#中DrawCurve的用法小结》本文主要介绍了C#中DrawCurve的用法小结,通常用于绘制一条平滑的曲线通过一系列给定的点,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 如何使用 DrawCurve 方法(不带弯曲程度)2. 如何使用 DrawCurve 方法(带弯曲程度)3.使用Dr

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数