(资料图)
本篇专栏主要分享我在研究C#反射时发现的有趣的问题,篇幅较短,但是对于动态来说有点长,所以干脆写专栏了。因为懒,所以无图,大家可以自行复现实验w
首先谈谈C#的类型。C#与Java一样,都有基本类型(值类型)和引用类型,但C#的基本类型,实际上是系统类的别名,也因此基本类型可以作为泛型构造类型(在Java中这是不可能的)。基本类型的特征是:有规定的默认值,例如int为0,bool为false等等。在C#中,基本类型为全小写,且在vs中为蓝色标识,还是很好辨认的。
再说说引用类型。引用类型顾名思义,就是在传递时,传递的不是值而是指针/别名,也就是说,如果我往一个函数传入一个引用类型的对象,则函数内对该形参的成员进行修改,一样会作用于实参。引用类型一般就是类,我们所定义的class类就是引用类型。一般的类名规则是Pascal命名法,即每个单词开头大写。
然而,虽然C#的string开头小写,但它却并不是基本类型,而是引用类型,意味着它的默认值为null。
在.Net 6前的版本中,不会强调引用类型的Nullable;而在.Net 6及之后,却默认提示“在退出构造函数时,不可为 null 的 属性“xxx”必须包含非 null 值”,这就意味着我们很多时候就会在引用类型的后面加上一个“?”,代表nullable。然而,由于引用类型无法体现Nullable<>,因此在反射中无法得知class?和class的区别,因此无法使用反射的方法进行区分。
但是,在.Net 6中,新增了一个NullabilityInfoContext类,通过其对象,可以获取属性的ReadState和WriteState。ReadState对于引用类型来说,一直都是NotNull,所以看不出区别。但是,WriteState在设置为class?时为Nullable,此时可以得知在定义时设置为nullable。
这确实是一个非常有意思的特性,尽管我认为它应该是反射中最基本的功能,但可能为了兼容性而没有增加,也是情有可原的。并且class?=Nullable<class>这一语法糖也说明C#开始像Windows一样有了巨大的历史包袱,尽管以后会增加很多实用的特性,也可以只用新的写法,但是无法抛弃旧的写法,会给入门者带来一些困惑(比如我)。哎,微软的东西就是这样,虽然感叹其精妙的设计,同时也被其shit山般的兼容性和较差的文档维护水平所困扰,真是又爱又恨。
最后简单谈谈我对C#的看法。C#的Lambda写法比较接近Javascript,让前端人感觉无比舒适(bushi),而且C#属性也节省了Get/Set方法的定义,我个人认为这才是封装的最佳方式。
C#目前的问题还是缺少生态,尤其是Blazor框架使用率较低,但却是微软强推的一个Web框架,目前我也在用,可以结合一些第三方UI库来使用,用法跟Vue比较相像,适合全栈开发。
C#仅仅是一个工具,能做出什么花来,取决于使用工具的人。我还是认为编程语言之间没有绝对优劣之分,仅仅是适合不同的应用场景罢了。我自己也学了很多语言,目前最常用的还是C++、PHP、Javascript和C#,它们都有各自的领域,没必要强行比较。
Copyright © 2015-2022 南方快报网版权所有 备案号:粤ICP备18023326号-21 联系邮箱:855 729 8@qq.com