CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

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新特性:可空的引用类型】

staticvoidMain(string[]args){nullableenablestringa=null;string?b=null;varc=a.Length;vard=b.Length;vare=b!.Length;nullabledisablestring?f=null;}

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

  • IDE会对a赋值为null的操作进行警告, 因为在约定中a不可为空,而b则不会警告,因为它可以为null
  • IDE会对a.Length的访问进行警告,因为已经静态推断出anull了;
  • IDE会对b.Length的访问进行警告,b类型可能为空;
  • b!.Length的访问操作不会被警告,因为这种形式的访问表示老子已经知道它可能为null了你闭嘴;
  • string? f =null语句会被IDE警告,因为上面已经把可为空的引用类型特性关闭了。

另外此特性不止支持enabledisable选项,还支持restore还原之前的设置,以及通过safeonlywarnings设置定制启用警告的范围,具体可参照其详细说明

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

【C 8.0新特性:using 声明】

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

staticvoidWriteLinesToFile(IEnumerable<string>lines){usingvarfile=newSystem.IO.StreamWriter("WriteLines2.txt");foreach(stringlineinlines){// If the line doesnt contain the word Second, write the line to the file.if(!line.Contains("Second")){file.WriteLine(line);}}// file is disposed here}

等价于:

staticvoidWriteLinesToFile(IEnumerable<string>lines){using(varfile=newSystem.IO.StreamWriter("WriteLines2.txt")){foreach(stringlineinlines){// If the line doesnt 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包:

对于客户端而言,还需要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";packageGreet;// The greeting service definition.serviceGreeter{// Sends a greetingrpcSayHello(HelloRequest)returns(HelloReply){}}// The request message containing the users name.messageHelloRequest{stringname=1;}// The response message containing the greetings.messageHelloReply{stringmessage=1;}

一个最简单的rpc服务器。

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

usingSystem.Threading.Tasks;usingGreet;usingGrpc.Core;namespaceGrpcService{publicclassGreeterService:Greeter.GreeterBase{publicoverrideTask<HelloReply>SayHello(HelloRequestrequest,ServerCallContextcontext){returnTask.FromResult(newHelloReply{Message=$"Hello { context.Method} "+request.Name});}}}

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

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

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

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

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

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

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

然后我们可以直接写:

usingSystem;usingSystem.Threading.Tasks;usingGreet;usingGrpc.Core;namespaceConsoleApp1{classProgram{staticasyncTaskMain(string[]args){varchannel=newChannel("localhost:50051",ChannelCredentials.Insecure);varclient=newGreeter.GreeterClient(channel);varreply=awaitclient.SayHelloAsync(newHelloRequest{Name="GreeterClient"});Console.WriteLine("Greeting: "+reply.Message);awaitchannel.ShutdownAsync();Console.WriteLine("Press any key to exit...");Console.ReadKey();}}}

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

其一是await channel.ShutdownAsync();

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

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

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容