C#8.0的两个有趣的新特性以及gRPC
最近每天忙着跑很多地方,回家就不想动了,没什么心情写东西。今天有空,稍微写一点。
下文中:
关于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相关推荐
- c# 路径下的最近文件夹_C#8.0的两个有趣的新特性以及gRPC
最近每天忙着跑很多地方,回家就不想动了,没什么心情写东西.今天有空,稍微写一点. 下文中: 关于C#语法特性的部分需要Visual Studio 2019支持. 关于.NET Core的部分需要安装. ...
- Swift 2.0初探:值得注意的新特性
转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...
- MySQL 8.0 在关系数据库方面有这些新特性
作者 | 捏造的信仰 原文 | https://segmentfault.com/a/1190000013803247 本文介绍几个 8.0 在关系数据库方面的主要新特性. 你可能已经知道 MySQL ...
- accept 返回0_从0开始理解Vite的主要新特性(一)
此文已同步到公众号[因卓诶]以及因卓诶博客: 从0开始理解Vite的主要新特性(一) - 因卓诶-爱分享爱原创的技术博客 ~ 个人博客www.yinzhuoei.com vite这个工具确实尤大在微 ...
- Kafka 2.8.0 正式发布,增加了哪些新特性?
导读:目前 Kafka 已经定位为一个分布式流式处理平台,它以高吞吐.可持久化.可水平扩展.支持流数据处理等多种特性而被广泛使用.目前越来越多的开源分布式处理系统如 Cloudera.Storm.Sp ...
- php7.0 yield,PHP7中生成器的新特性 yield-from amp;amp; return-values
生成器委托 简单地翻译官方文档的描述: PHP7中,通过生成器委托(yield from),可以将其他生成器.可迭代的对象.数组委托给外层生成器.外层的生成器会先顺序 yield 委托出来的值,然后继 ...
- CentOS 7.6 MySQL 8.0 RPM包方式安装及新特性介绍
一.MySQL 8.0新特性: 1.默认字符集由latin1变为utf8mb4 2.MyISAM系统表全部换成InnoDB表 3.自增主键AUTO_INCREMENT的值支持持久化 4.InnoDB表 ...
- 重磅!阿里云MongoDB 5.0发布,速来围观新特性
简介:2021年9月29日下午,阿里云数据库与MongoDB共同发布了阿里云MongoDB 5.0.MongoDB于2021年7月中发布最新5.0版本,阿里云MongoDB率先跟进官方最新版本能力,快 ...
- mysql rpm 安装6_CentOS 7.6 MySQL 8.0 RPM包方式安装及新特性介绍
一.MySQL 8.0新特性: 1.默认字符集由latin1变为utf8mb4 2.MyISAM系统表全部换成InnoDB表 3.自增主键AUTO_INCREMENT的值支持持久化 4.InnoDB表 ...
最新文章
- Why Sleeping May Be More Important Than Studying
- java.util.concurrent.Callable 接口 源码
- 嵌入式系统在井下煤炭井下监控系统的应用
- 亲测好用!如何快速访问github网站?
- ORACLE nvarchar2和varchar2的区别
- hdu5249KPI动态中位数(两个set)
- 移动开发的罗曼蒂克消亡史
- Redis缓存击穿和缓存雪崩、缓存穿透以及对应的解决方案
- 微带线特性阻抗计算公式_利用HFSS计算微带线的特性阻抗
- 吴恩达《机器学习》学习笔记六——过拟合与正则化
- Java 工具类 - MD5Util
- 求生欲强烈!HTC官方回应并未退出中国市场
- SQL Server着眼于非数字数据类型
- 多个notification引发的问题
- 我的第一个项目,二维码手机排队系统
- Visual Leak Detector(vld)无法显示内存泄露文件名称与行号
- oracle数据库查询空间大小,Oracle查看数据库空间使用情况
- android 微信朋友圈相册封面裁剪的小秘密
- OpenCV-绘制同心圆
- windows10启动项修复||an operating system wasn't found解决办法