本文主要是介绍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问--为什么值类型不允许定义无参构造函数?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!