日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#8.0的两个有趣的新特性以及gRPC

發(fā)布時間:2023/12/4 C# 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#8.0的两个有趣的新特性以及gRPC 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近每天忙著跑很多地方,回家就不想動了,沒什么心情寫東西。今天有空,稍微寫一點。

下文中:

  • 關(guān)于C#語法特性的部分需要Visual Studio 2019支持。

  • 關(guān)于.NET Core的部分需要安裝.NET 3.0 Preview4,低版本或許也可以但我沒實驗。

  • 如果要在最新版的VS2019中使用.NET 3.0,可能需要在?選項?-?解決方案與項目-?ASP.NET Core?中啟用 使用?.NET Core SDK?預(yù)覽版 選項。

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

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

復制以上簡單的代碼到IDE就能展現(xiàn)這個特性的特點與用法:

  • IDE會對?a?賦值為?null?的操作進行警告, 因為在約定中?a?不可為空,而?b?則不會警告,因為它可以為?null?;

  • IDE會對?a.Length?的訪問進行警告,因為已經(jīng)靜態(tài)推斷出?a?為?null?了;

  • IDE會對?b.Length?的訪問進行警告,b?類型可能為空;

  • b!.Length?的訪問操作不會被警告,因為這種形式的訪問表示老子已經(jīng)知道它可能為?null?了你閉嘴;

  • string? f =null?語句會被IDE警告,因為上面已經(jīng)把可為空的引用類型特性關(guān)閉了。

另外此特性不止支持?enable?和?disable?選項,還支持?restore?還原之前的設(shè)置,以及通過?safeonly?或?warnings?設(shè)置“定制”啟用警告的范圍,具體可參照其?詳細說明?。

我們可以發(fā)現(xiàn)這個特性的的實質(zhì)其實是一個“柔性”斷言,啟用后IDE會對部分代碼進行警告提示,督促我們進行處理,但也止于此了。它非常靈活,新項目啟用此特性是值得的,但舊項目也沒必要升級。

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

這里可以直接看官網(wǎng)的例子:

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?關(guān)鍵字修飾的變量聲明,它在作用域結(jié)束后會自動釋放。一開始我沒明白這個有什么意義,今天和?談到某種情況,就是某些類型之所以會繼承?IDispose?接口,可能是基于對語義或設(shè)計實現(xiàn)上的軟需求,并非它一定需要調(diào)用?Dispose?方法才能夠釋放(比如?ProcessModule Class (System.Diagnostics)?)。

在這種情況下,對于我這樣的強迫癥患者而言,明知道沒必要,但也得不厭其煩地?try finally?或者?using{}。有了這個特性,在寫類似的代碼的時候,可以只多加幾個字就讓心情舒暢,是強迫癥患者的福音。另外在進行一些很常見的操作比如IO(Stream)、摘要計算(HashAlgorithm)時,可以少寫一些代碼。

【ASP dot NET Core 3.0中的 gRPC 服務(wù)】

.NET CORE使用gRPC服務(wù)需要用到兩個Nuget包:

  • 運行時:Google.Protobuf

  • 支持套件:Grpc.Tools

對于客戶端而言,還需要?Grpc.Core?包的支持。

Google.Protobuf?不必解釋,Grpc.Core?是一系列客戶端要用到的API,而?Grpc.Tools?的牛逼之處在于不用編譯 *.proto 文件即可直接在C#中引用它……

對于.NET Core 2.1 或 2.2而言使用 gPRC 服務(wù)還需要手寫微量代碼(XXX.BindService方法),而到了.NET CORE 3.0,引用?Grpc.AspNetCore.Server?包后即可直接以慣常的配置方式(AddXXX)直接使用此服務(wù)。

這里偷個懶,直接用 Visual Studio 2019+.NET CORE 3.0做示例。VS 2019中有 gRPC 服務(wù)器的模板,選擇后直接會創(chuàng)建一個現(xiàn)成的新手示例。

我們一定會注意到?Startup?類中?ConfigureServices?方法的語句?services.AddGrpc()?。這個是慣例,不用去管,重點看?Configure?方法里的代碼片段:

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

此處和?WCF?的思想類似,將服務(wù)添加到路由終結(jié)點,讓客戶端連接。

然后可以看位于?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服務(wù)器。

然后再看?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

});
}

}
}

代碼的實現(xiàn)思路很好理解。我們可以注意到我們能夠直接導入?Greet?命名空間,這是因為它已經(jīng)被Grpc.Tools?生成到了項目下?obj?文件夾的項目緩存中。

最后的一個重點在項目配置文件(*.csproj)中的?ItemGroup?節(jié)點:

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

這就是在項目中引用proto文件的方法,具體細節(jié)詳見官方說明:gRPC services with C#?。

然后我們可以創(chuàng)建個客戶端嘗試與服務(wù)端通訊,建立一個命令行程序,引用?Google.Protobuf、Grpc.Tools以及?Grpc.Core?包,同時在項目配置文件中的?ItemGroup?節(jié)點中加入一句話:

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

(我是在服務(wù)端項目同目錄建立的客戶端項目,所以路徑直接這么寫就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();
}
}
}

創(chuàng)建頻道——創(chuàng)建連接——發(fā)送請求——關(guān)閉頻道,簡單易懂。我們著重看兩點。

其一是?await channel.ShutdownAsync();:

在程序退出前,最好或者說必須關(guān)閉曾經(jīng)創(chuàng)建過的頻道。

另一個就是我們會注意到此處代碼中的Greeter?類所公開的接口完全是面向客戶端的。而同理,上面服務(wù)器中的?Greeter?類公開的接口則是面向服務(wù)器的,這是受項目配置中?GrpcServices=Client|Server的影響,非常智能化……

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

.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?

總結(jié)

以上是生活随笔為你收集整理的C#8.0的两个有趣的新特性以及gRPC的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。