日志

一个茴字有三种写法——吐槽C#9.0的Records

 来源    2020-05-23    1  

最近是微软开了Build 2020大会,由于疫情原因,改成了在线举行,Build大会上,C#公布9.0版本。

我个人对于C#的更新向来都是喜闻乐见,乐于接受的,对于博客园上某些人天天嘲讽C#只会增加语法糖的人,我向来对他们不屑一顾,认为他们是井底之蛙。

因此我仔细看了微软发的文章Welcome to C# 9.0,准备好好观摩和学习。但当我看到Records语法时,我就隐隐感觉C#这样玩语法糖要翻车了。

后来看到知乎上的问题如何评价即将发布的 C# 9.0?,我稍加思索,愈发觉得Records语法完全是大型翻车现场,因此整理出来我认为的Records的翻车点(兼吐槽)。

首先看官方给出的Records样例

public data class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}

第一个吐槽点:data class声明有必要吗?如果要多加一个data关键字,直接用record不好吗,如果不加关键字,为什么不用readonly class啊。

public record Person {}
public readonly class Person {}

第二个吐槽点,官方给出上面的等价定义

public data class Person { string FirstName; string LastName; }

看到这里我几乎晕了过去,确定这两者等价吗?语言的一致性破坏的损失殆尽?不信?如果把data这个词去掉的话。

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
public class Person
{
    string FirstName; 
    string LastName;
}

但凡任何一个C#初学者,都不会说上面等价,因为那段定义等于

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
public class Person
{
    private string FirstName { get; set; }; 
    private string LastName { get; set; };
}

这怎么等价?也就是说,加了data一个关键词,后面我们对C#语法的掌握就要被推翻?!

Ok,上面喷完了,我们再来看看官方还有第3种定义方法

public data class Person(string FirstName, string LastName);

这种record定义非常漂亮。但,一个record有3种定义方法?!你说之前的LINQ有2种写法,我认了,毕竟看起来更加简单直观,更像sql。但record是现代版的一个茴字有3种写法啊!

总结,这次Records语法,看起来漂亮,实际上是一场巨大的灾难。归根结底在于对于Records的定位不够清晰。如果要真正的Immutable,那么Records应该是类似Tuple的存在,应该和Class切割开,走类似Rust的Stuct的路子,加上UnionType,EnumClass就是起飞。如果想要一个看起来Immutable实际上是Mutable的Class的话,还不如想想怎么简化Class语法,但要注意简化的过程中要保持一致性。什么?你要Mutable?不就是Class嘛。

下面是一些碎碎念时间。

自从C#之父Anders去做Typescript之后,能看出C#团队还是尽心尽力改善C#的,比如模式匹配(一点一点加),可空引用类型,类型推导的new,Indies和Ranges,。

但不得不说,他们的品味偶尔也会下滑。

比如说前几天在博客园Rwing发过的的强制非空语法,给人一种画蛇添足的感觉,但考虑到历史包袱,可以理解。

Deconstruct是我认为另外一个败笔。对于自定义类型的解构,完全没有任何必要重新定义一个Deconstruct方法,模仿Typescript(Anders大神手笔)即可。如果要解构一个经过运算的东西,就应该重新定义另一个方法返回出来。解构解构,就是将原本值拿出来,而非一个不知道怎么运算出来东西。

var { name: x, age: y } = new { name: "xx", age: 26 }

对了,还有这次模式匹配中加入了and和or运算符,最迷惑的是,if语句中不能用and和or,只能用&&和||。我只能说,闲的蛋疼,又不是Python,加来干什么。

我吐槽完了,大家可以顶/踩我了。大家也可以去上面知乎问题发表意见,共同讨论C#语言。

相关文章
“茴”字有四种写法,this也是一样
日志说到这个地方又想起以前高中还是初中学的<孔乙己>这个梗,但是这里的this显然实用性比那个要大很多,哈哈. 简单来说,this有四种应用场景,分别是在构造函数上.对象属性中.普通函数中.c ...
1
委托、事件 茴字有几种写法
日志如何定义一个方法变量 委托与事件最大的作用其实就是可以让方法(函数)成为一个变量,然后再外部实例化这个类时定义这个方法.但是方法不属于基本类型,不能像定义普通变量一样的去声明它,如我们可以定义一个速度 ...
1
举几个单例模式的例子——茴香豆的茴字有几种写法?
日志勤加载(饿汉模式) public class EagerSingleton { private EagerSingleton() { } private static EagerSingleton i ...
python – 找一个连字的辅音
问答我需要一个代码来显示我的连续辅音.例如对于suiteConsonnes("concertation")我需要获取["c","nc",&quo ...
Javascript – 如何大写第一个字母的每个单词,像一个2字的城市?
问答Possible Duplicate: 07000 我的JS醒来时,城市有一个词: > cHIcaGO ==>芝加哥 但是当它 > san diego ==>圣地亚哥 我如何使 ...
html – 如何强制换行DIV中的一个低字?
问答好吧,这真的让我困惑.我有一些内容在一个div像这样: <div style="background-color: green; width: 200px; height: 300px ...
1
php – 从mySQL中拉第一个X字(不只是字符)
问答我想从数据库字段中拉出第一个X字,用于预览.基本上如果一个字段的内容是 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. M ...
iphone – UILabel有多条线来截断一个长字
问答我有一个UIlabel视图,允许显示两行字符串.但就我而言,只有一个长话.无论我将换行模式设置为UILineBreakModeTailTruncation还是UILineBreakModeWordWr ...
1
java – Spring MVC一个输入字段表单
问答Spring MVC中最好的方式是只向表单中的一个字段发送一个字段?我需要发送选择框值,但我也希望选择框预先填充正确的值. 通常我会有一些表单支持对象,并将他绑定到表单,但是当我只有一个字段要发送时, ...
1
iPhone目标c:检测一个“真实”字
问答我需要一个(快速和脏的)解决方案来基本检测某个NSString是否是一个"真实"的单词,也就是说,如果它在字典中.所以基本上,一个非常简单的拼写检查.有人知道有什么办法吗?基本上, ...
1
javascript – 最快的算法来绘制一个填字游戏网格?
问答我正在渲染细胞网格,非常像您在纵横字谜中找到的网格,但使用四种不同的颜色来填充每个单元格(不仅是黑色或白色). 网格大小约为160×120,我需要尽可能快地呈现,因为它将用于显示Cellular au ...
1
js函数声明外面使用小括号括起来再接一个小括号的写法
日志js函数声明外面使用小括号括起来再接一个小括号的写法 (function(){})(); (function(){}()); !function(){}(); 总结ps:意思将函数声明变成,直接执行的 ...
一个炫字都不够??!!!手把手带你打造3D自定义view
日志分享一则最近流行的笑话: 最新科学研究表明:寒冷可以使人保持年轻,楼下的王大爷表示虽然今年已经60多岁了,但是仍然冷的跟孙子一样. 呃.好吧,这个冬天确实有点冷,在广州活生生的把我这个原生北方人,冻成 ...
1
js => ES6一个新的函数写法
日志var arr='aaabbccaa'; var info = arr.split('').reduce((p, k) => (p[k]++ || (p[k] = 1), p), {}); co ...
从一个小程序跳到另一个小程序的写法
日志成功做完了哈哈哈 首先我试了navigateToMiniProgram ,已经废弃了,不行 下面的可以 <block wx:for="{{carList}}"> < ...
C#中,switch case语句中多个值匹配一个代码块的写法
日志switch (num) { case 1: Response.Write("1"); break; case 2: case 3: Response.Write("2| ...
1
Java套接字:你可以从一个线程发送并在另一个线程上接收吗?
问答这可能是一个非常基本的问题,但我很难找到答案. 是否可以让一个线程写入Socket的输出流,而另一个线程正在从Socket的输入流中读取? 编辑:这是与外部服务器通信的客户端应用程序.我并不是想让两个 ...
1
一次将数据写入多个套接字(一个Syscall)
问答我有一个用libevent编写的TCP-Brodcast-Server,它执行以下操作: Read data from a client ... Transform the data ... //Wr ...
2
使用UNIX套接字将文件描述符从一个程序传递到同一主机上的另一个程序
问答我有两个prgrams让我们说prog1和prog2.我正在用prog1打开一个文件并进行一些操作 在上面.现在没有关闭prog1中的文件,我使用unix将其文件描述符发送到prog2 套接字然后在其 ...
1
为什么Java ServerSocket accept()返回一个与ServerSocket具有相同端口的套​​接字?
问答在服务器端,我使用此代码: ServerSocket server = new ServerSocket(1234); Socket server_socket = server.accept(); ...
1