最近每天忙着跑很多地方,回家就不想动了,没什么心情写东西。今天有空,稍微写一点。

下文中:

  • 关于C#语法特性的部分需要Visual Studio 2019支持。

  • 关于.NET Core的部分需要安装.NET 3.0 Preview4,低版本或许也可以但我没实验。

  • 如果要在最新版的VS2019中使用.NET 3.0,可能需要在 选项 - 解决方案与项目ASP.NET Core 中启用 使用 .NET Core SDK 预览版 选项。

【C# 8.0新特性:可空的引用类型】

static void Main(string[] args){#nullable enablestring a = null;string? b = null;var c = a.Length;var d = b.Length;var e = b!.Length;#nullable disablestring? f = null;}

复制以上简单的代码到IDE就能展现这个特性的特点与用法:

  • IDE会对 a 赋值为 null 的操作进行警告, 因为在约定中 a 不可为空,而 b 则不会警告,因为它可以为 null ;

  • IDE会对 a.Length 的访问进行警告,因为已经静态推断出 a 为 null 了;

  • IDE会对 b.Length 的访问进行警告,b 类型可能为空;

  • b!.Length 的访问操作不会被警告,因为这种形式的访问表示老子已经知道它可能为 null 了你闭嘴;

  • string? f =null 语句会被IDE警告,因为上面已经把可为空的引用类型特性关闭了。

另外此特性不止支持 enable 和 disable 选项,还支持 restore 还原之前的设置,以及通过 safeonly 或 warnings 设置“定制”启用警告的范围,具体可参照其 详细说明 。

我们可以发现这个特性的的实质其实是一个“柔性”断言,启用后IDE会对部分代码进行警告提示,督促我们进行处理,但也止于此了。它非常灵活,新项目启用此特性是值得的,但旧项目也没必要升级。

【C# 8.0新特性:using 声明】

这里可以直接看官网的例子:

static void WriteLinesToFile(IEnumerable<string> lines){using var file = new System.IO.StreamWriter("WriteLines2.txt");foreach (string line in lines){// If the line doesn't contain the word 'Second', write the line to the file.        if (!line.Contains("Second")){file.WriteLine(line);}}// file is disposed here}

等价于:

static void WriteLinesToFile(IEnumerable<string> lines){using (var file = new System.IO.StreamWriter("WriteLines2.txt")){foreach (string line in lines){// If the line doesn't contain the word 'Second', write the line to the file.            if (!line.Contains("Second")){file.WriteLine(line);}}} // file is disposed here}

也就是说使用 using 关键字修饰的变量声明,它在作用域结束后会自动释放。一开始我没明白这个有什么意义,今天和 谈到某种情况,就是某些类型之所以会继承 IDispose 接口,可能是基于对语义或设计实现上的软需求,并非它一定需要调用 Dispose 方法才能够释放(比如 ProcessModule Class (System.Diagnostics) )。

在这种情况下,对于我这样的强迫症患者而言,明知道没必要,但也得不厌其烦地 try finally 或者 using{}。有了这个特性,在写类似的代码的时候,可以只多加几个字就让心情舒畅,是强迫症患者的福音。另外在进行一些很常见的操作比如IO(Stream)、摘要计算(HashAlgorithm)时,可以少写一些代码。

【ASP dot NET Core 3.0中的 gRPC 服务】

.NET CORE使用gRPC服务需要用到两个Nuget包:

  • 运行时:Google.Protobuf

  • 支持套件:Grpc.Tools

对于客户端而言,还需要 Grpc.Core 包的支持。

Google.Protobuf 不必解释,Grpc.Core 是一系列客户端要用到的API,而 Grpc.Tools 的牛逼之处在于不用编译 *.proto 文件即可直接在C#中引用它……

对于.NET Core 2.1 或 2.2而言使用 gPRC 服务还需要手写微量代码(XXX.BindService方法),而到了.NET CORE 3.0,引用 Grpc.AspNetCore.Server 包后即可直接以惯常的配置方式(AddXXX)直接使用此服务。

这里偷个懒,直接用 Visual Studio 2019+.NET CORE 3.0做示例。VS 2019中有 gRPC 服务器的模板,选择后直接会创建一个现成的新手示例。

我们一定会注意到 Startup 类中 ConfigureServices 方法的语句 services.AddGrpc() 。这个是惯例,不用去管,重点看 Configure 方法里的代码片段:

app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapGrpcService<GreeterService>();}); 

此处和 WCF 的思想类似,将服务添加到路由终结点,让客户端连接。

然后可以看位于 Protos 文件夹下的 greet.proto 文件:

syntax = "proto3";package Greet;// The greeting service definition.service Greeter {  // Sends a greeting  rpc SayHello (HelloRequest) returns (HelloReply) {}}// The request message containing the user's name.message HelloRequest {  string name = 1;}// The response message containing the greetings.message HelloReply {  string message = 1;}

一个最简单的rpc服务器。

然后再看 Services 文件夹下的 GreeterService.cs 文件:

using System.Threading.Tasks;using Greet;using Grpc.Core;

namespace GrpcService{public class GreeterService : Greeter.GreeterBase{public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context){return Task.FromResult(new HelloReply{Message =$"Hello { context.Method} " + request.Name

});}

}}

代码的实现思路很好理解。我们可以注意到我们能够直接导入 Greet 命名空间,这是因为它已经被Grpc.Tools 生成到了项目下 obj 文件夹的项目缓存中。

最后的一个重点在项目配置文件(*.csproj)中的 ItemGroup 节点:

   <Protobuf Include="Protos\greet.proto" GrpcServices="Server" Generator="MSBuild:Compile" />

这就是在项目中引用proto文件的方法,具体细节详见官方说明:gRPC services with C# 。

然后我们可以创建个客户端尝试与服务端通讯,建立一个命令行程序,引用 Google.Protobuf、Grpc.Tools以及 Grpc.Core 包,同时在项目配置文件中的 ItemGroup 节点中加入一句话:

<Protobuf Include="..\GrpcService\Protos\greet.proto" GrpcServices="Client" /> 

(我是在服务端项目同目录建立的客户端项目,所以路径直接这么写就OK)

然后我们可以直接写:

using System;using System.Threading.Tasks;using Greet;using Grpc.Core;namespace ConsoleApp1{class Program{static async Task Main(string[] args){var channel = new Channel("localhost:50051", ChannelCredentials.Insecure);var client = new Greeter.GreeterClient(channel);var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" });Console.WriteLine("Greeting: " + reply.Message);await channel.ShutdownAsync();Console.WriteLine("Press any key to exit...");Console.ReadKey();}}}

创建频道——创建连接——发送请求——关闭频道,简单易懂。我们着重看两点。

其一是 await channel.ShutdownAsync();

在程序退出前,最好或者说必须关闭曾经创建过的频道。

另一个就是我们会注意到此处代码中的Greeter 类所公开的接口完全是面向客户端的。而同理,上面服务器中的 Greeter 类公开的接口则是面向服务器的,这是受项目配置中 GrpcServices=Client|Server的影响,非常智能化……

原文地址:https://zhuanlan.zhihu.com/p/63779162

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

C#8.0的两个有趣的新特性以及gRPC相关推荐

  1. c# 路径下的最近文件夹_C#8.0的两个有趣的新特性以及gRPC

    最近每天忙着跑很多地方,回家就不想动了,没什么心情写东西.今天有空,稍微写一点. 下文中: 关于C#语法特性的部分需要Visual Studio 2019支持. 关于.NET Core的部分需要安装. ...

  2. Swift 2.0初探:值得注意的新特性

    转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...

  3. MySQL 8.0 在关系数据库方面有这些新特性

    作者 | 捏造的信仰 原文 | https://segmentfault.com/a/1190000013803247 本文介绍几个 8.0 在关系数据库方面的主要新特性. 你可能已经知道 MySQL ...

  4. accept 返回0_从0开始理解Vite的主要新特性(一)

    此文已同步到公众号[因卓诶]以及因卓诶博客: 从0开始理解Vite的主要新特性(一) - 因卓诶-爱分享爱原创的技术博客 ~ 个人博客​www.yinzhuoei.com vite这个工具确实尤大在微 ...

  5. Kafka 2.8.0 正式发布,增加了哪些新特性?

    导读:目前 Kafka 已经定位为一个分布式流式处理平台,它以高吞吐.可持久化.可水平扩展.支持流数据处理等多种特性而被广泛使用.目前越来越多的开源分布式处理系统如 Cloudera.Storm.Sp ...

  6. php7.0 yield,PHP7中生成器的新特性 yield-from amp;amp; return-values

    生成器委托 简单地翻译官方文档的描述: PHP7中,通过生成器委托(yield from),可以将其他生成器.可迭代的对象.数组委托给外层生成器.外层的生成器会先顺序 yield 委托出来的值,然后继 ...

  7. CentOS 7.6 MySQL 8.0 RPM包方式安装及新特性介绍

    一.MySQL 8.0新特性: 1.默认字符集由latin1变为utf8mb4 2.MyISAM系统表全部换成InnoDB表 3.自增主键AUTO_INCREMENT的值支持持久化 4.InnoDB表 ...

  8. 重磅!阿里云MongoDB 5.0发布,速来围观新特性

    简介:2021年9月29日下午,阿里云数据库与MongoDB共同发布了阿里云MongoDB 5.0.MongoDB于2021年7月中发布最新5.0版本,阿里云MongoDB率先跟进官方最新版本能力,快 ...

  9. mysql rpm 安装6_CentOS 7.6 MySQL 8.0 RPM包方式安装及新特性介绍

    一.MySQL 8.0新特性: 1.默认字符集由latin1变为utf8mb4 2.MyISAM系统表全部换成InnoDB表 3.自增主键AUTO_INCREMENT的值支持持久化 4.InnoDB表 ...

最新文章

  1. Why Sleeping May Be More Important Than Studying
  2. java.util.concurrent.Callable 接口 源码
  3. 嵌入式系统在井下煤炭井下监控系统的应用
  4. 亲测好用!如何快速访问github网站?
  5. ORACLE nvarchar2和varchar2的区别
  6. hdu5249KPI动态中位数(两个set)
  7. 移动开发的罗曼蒂克消亡史
  8. Redis缓存击穿和缓存雪崩、缓存穿透以及对应的解决方案
  9. 微带线特性阻抗计算公式_利用HFSS计算微带线的特性阻抗
  10. 吴恩达《机器学习》学习笔记六——过拟合与正则化
  11. Java 工具类 - MD5Util
  12. 求生欲强烈!HTC官方回应并未退出中国市场
  13. SQL Server着眼于非数字数据类型
  14. 多个notification引发的问题
  15. 我的第一个项目,二维码手机排队系统
  16. Visual Leak Detector(vld)无法显示内存泄露文件名称与行号
  17. oracle数据库查询空间大小,Oracle查看数据库空间使用情况
  18. android 微信朋友圈相册封面裁剪的小秘密
  19. OpenCV-绘制同心圆
  20. windows10启动项修复||an operating system wasn't found解决办法

热门文章

  1. 从Boxee的Amie Street访问音乐
  2. pc端文本_使用即将推出的Windows功能从PC发送文本
  3. Linux本地yum源配置以及使用yum源安装gcc编译环境
  4. (三)Controller接口控制器详解(二)
  5. vue-cli 3.0配置webpack目录别名alias
  6. spring boot微服务通用部署启动脚本
  7. ThinkPHP多次重复提交问题的根源
  8. 安装debian的zabbix-agent客户端
  9. 自制H3C交换机CONSOLE线
  10. 第十一章项目沟通管理重点--转载