.NET 6新增的20个API介绍
dateonly & timeonly
.net 6 引入了两种期待已久的类型 - dateonly 和 timeonly, 它们分别代表datetime的日期和时间部分。
dateonly dateonly = new(2021, 9, 25); console.writeline(dateonly); timeonly timeonly = new(19, 0, 0); console.writeline(timeonly); dateonly dateonlyfromdate = dateonly.fromdatetime(datetime.now); console.writeline(dateonlyfromdate); timeonly timeonlyfromdate = timeonly.fromdatetime(datetime.now); console.writeline(timeonlyfromdate);
parallel.foreachasync
它可以控制多个异步任务的并行度。
var userhandlers = new[] { "users/okyrylchuk", "users/jaredpar", "users/davidfowl" }; using httpclient client = new() { baseaddress = new uri("https://api.github.com"), }; client.defaultrequestheaders.useragent.add(new productinfoheadervalue("dotnet", "6")); paralleloptions options = new() { maxdegreeofparallelism = 3 }; await parallel.foreachasync(userhandlers, options, async (uri, token) => { var user = await client.getfromjsonasync<githubuser>(uri, token); console.writeline($"name: {user.name}\nbio: {user.bio}\n"); }); public class githubuser { public string name { get; set; } public string bio { get; set; } } // output: // name: david fowler // bio: partner software architect at microsoft on the asp.net team, creator of signalr // // name: oleg kyrylchuk // bio: software developer | dotnet | c# | azure // // name: jared parsons // bio: developer on the c# compiler
argumentnullexception.throwifnull()
argumentnullexception 的小改进, 在抛出异常之前不需要在每个方法中检查 null, 现在只需要写一行, 和 response.ensuresuccessstatuscode();
类似。
examplemethod(null); void examplemethod(object param) { argumentnullexception.throwifnull(param); // do something }
priorityqueue
.net 6 新增的数据结构, priorityqueue, 队列每个元素都有一个关联的优先级,它决定了出队顺序, 编号小的元素优先出列。
priorityqueue<string, int> priorityqueue = new(); priorityqueue.enqueue("second", 2); priorityqueue.enqueue("fourth", 4); priorityqueue.enqueue("third 1", 3); priorityqueue.enqueue("third 2", 3); priorityqueue.enqueue("first", 1); while (priorityqueue.count > 0) { string item = priorityqueue.dequeue(); console.writeline(item); } // output: // first // second // third 2 // third 1 // fourth
randomaccess
提供基于偏移量的 api,用于以线程安全的方式读取和写入文件。
using safefilehandle handle = file.openhandle("file.txt", access: fileaccess.readwrite); // write to file byte[] strbytes = encoding.utf8.getbytes("hello world"); readonlymemory<byte> buffer1 = new(strbytes); await randomaccess.writeasync(handle, buffer1, 0); // get file length long length = randomaccess.getlength(handle); // read from file memory<byte> buffer2 = new(new byte[length]); await randomaccess.readasync(handle, buffer2, 0); string content = encoding.utf8.getstring(buffer2.toarray()); console.writeline(content); // hello world
periodictimer
认识一个完全异步的“periodictimer”, 更适合在异步场景中使用, 它有一个方法 waitfornexttickasync
。
// one constructor: public periodictimer(timespan period) using periodictimer timer = new(timespan.fromseconds(1)); while (await timer.waitfornexttickasync()) { console.writeline(datetime.utcnow); } // output: // 13 - oct - 21 19:58:05 pm // 13 - oct - 21 19:58:06 pm // 13 - oct - 21 19:58:07 pm // 13 - oct - 21 19:58:08 pm // 13 - oct - 21 19:58:09 pm // 13 - oct - 21 19:58:10 pm // 13 - oct - 21 19:58:11 pm // 13 - oct - 21 19:58:12 pm // ...
metrics api
.net 6 实现了 opentelemetry metrics api 规范, 内置了指标api, 通过 meter 类创建下面的指标
- counter
- histogram
- observablecounter
- observablegauge
使用的方法如下:
var builder = webapplication.createbuilder(args); var app = builder.build(); // create meter var meter = new meter("metricsapp", "v1.0"); // create counter counter<int> counter = meter.createcounter<int>("requests"); app.use((context, next) => { // record the value of measurement counter.add(1); return next(context); }); app.mapget("/", () => "hello world"); startmeterlistener(); app.run(); // create and start meter listener void startmeterlistener() { var listener = new meterlistener(); listener.instrumentpublished = (instrument, meterlistener) => { if (instrument.name == "requests" && instrument.meter.name == "metricsapp") { // start listening to a specific measurement recording meterlistener.enablemeasurementevents(instrument, null); } }; listener.setmeasurementeventcallback<int>((instrument, measurement, tags, state) => { console.writeline($"instrument {instrument.name} has recorded the measurement: {measurement}"); }); listener.start(); }
检查元素是否可为空的反射api
它提供来自反射成员的可空性信息和上下文:
- parameterinfo 参数
- fieldinfo 字段
- propertyinfo 属性
- eventinfo 事件
var example = new example(); var nullabilityinfocontext = new nullabilityinfocontext(); foreach (var propertyinfo in example.gettype().getproperties()) { var nullabilityinfo = nullabilityinfocontext.create(propertyinfo); console.writeline($"{propertyinfo.name} property is {nullabilityinfo.writestate}"); } // output: // name property is nullable // value property is notnull class example { public string? name { get; set; } public string value { get; set; } }
检查嵌套元素是否可为空的反射api
它允许您获取嵌套元素的可为空的信息, 您可以指定数组属性必须为非空,但元素可以为空,反之亦然。
type exampletype = typeof(example); propertyinfo notnullablearraypi = exampletype.getproperty(nameof(example.notnullablearray)); propertyinfo nullablearraypi = exampletype.getproperty(nameof(example.nullablearray)); nullabilityinfocontext nullabilityinfocontext = new(); nullabilityinfo notnullablearrayni = nullabilityinfocontext.create(notnullablearraypi); console.writeline(notnullablearrayni.readstate); // notnull console.writeline(notnullablearrayni.elementtype.readstate); // nullable nullabilityinfo nullablearrayni = nullabilityinfocontext.create(nullablearraypi); console.writeline(nullablearrayni.readstate); // nullable console.writeline(nullablearrayni.elementtype.readstate); // nullable class example { public string?[] notnullablearray { get; set; } public string?[]? nullablearray { get; set; } }
processid & processpath
直接通过 environment 获取进程id和路径。
int processid = environment.processid string path = environment.processpath; console.writeline(processid); console.writeline(path);
configuration 新增 getrequiredsection()
和 di 的 getrequiredservice() 是一样的, 如果缺失, 则会抛出异常。
webapplicationbuilder builder = webapplication.createbuilder(args); webapplication app = builder.build(); mysettings mysettings = new(); // throws invalidoperationexception if a required section of configuration is missing app.configuration.getrequiredsection("mysettings").bind(mysettings); app.run(); class mysettings { public string? settingvalue { get; set; } }
cspng 密码安全伪随机数生成器
您可以从密码安全伪随机数生成器 (cspng) 轻松生成随机值序列。
它对于以下场景中很有用:
密钥生成
随机数
某些签名方案中的盐
// fills an array of 300 bytes with a cryptographically strong random sequence of values. // getbytes(byte[] data); // getbytes(byte[] data, int offset, int count) // getbytes(int count) // getbytes(span<byte> data) byte[] bytes = randomnumbergenerator.getbytes(300);
native memory api
.net 6 引入了一个新的 api 来分配本机内存, nativememory 有分配和释放内存的方法。
unsafe { byte* buffer = (byte*)nativememory.alloc(100); nativememory.free(buffer); /* this class contains methods that are mainly used to manage native memory. public static class nativememory { public unsafe static void* alignedalloc(nuint bytecount, nuint alignment); public unsafe static void alignedfree(void* ptr); public unsafe static void* alignedrealloc(void* ptr, nuint bytecount, nuint alignment); public unsafe static void* alloc(nuint bytecount); public unsafe static void* alloc(nuint elementcount, nuint elementsize); public unsafe static void* alloczeroed(nuint bytecount); public unsafe static void* alloczeroed(nuint elementcount, nuint elementsize); public unsafe static void free(void* ptr); public unsafe static void* realloc(void* ptr, nuint bytecount); }*/ }
power of 2
.net 6 引入了用于处理 2 的幂的新方法。
- 'ispow2' 判断指定值是否为 2 的幂。
- 'rounduptopowerof2' 将指定值四舍五入到 2 的幂。
// ispow2 evaluates whether the specified int32 value is a power of two. console.writeline(bitoperations.ispow2(128)); // true // rounduptopowerof2 rounds the specified t:system.uint32 value up to a power of two. console.writeline(bitoperations.rounduptopowerof2(200)); // 256
waitasync on task
您可以更轻松地等待异步任务执行, 如果超时会抛出 “timeoutexception”
task operationtask = dosomethinglongasync(); await operationtask.waitasync(timespan.fromseconds(5)); async task dosomethinglongasync() { console.writeline("dosomethinglongasync started."); await task.delay(timespan.fromseconds(10)); console.writeline("dosomethinglongasync ended."); } // output: // dosomethinglongasync started. // unhandled exception.system.timeoutexception: the operation has timed out.
新的数学api
新方法:
- sincos
- reciprocalestimate
- reciprocalsqrtestimate
新的重载:
- min, max, abs, sign, clamp 支持 nint 和 nuint
- divrem 返回一个元组, 包括商和余数。
// new methods sincos, reciprocalestimate and reciprocalsqrtestimate // simultaneously computes sin and cos (double sin, double cos) = math.sincos(1.57); console.writeline($"sin = {sin}\ncos = {cos}"); // computes an approximate of 1 / x double recest = math.reciprocalestimate(5); console.writeline($"reciprocal estimate = {recest}"); // computes an approximate of 1 / sqrt(x) double recsqrtest = math.reciprocalsqrtestimate(5); console.writeline($"reciprocal sqrt estimate = {recsqrtest}"); // new overloads // min, max, abs, clamp and sign supports nint and nuint (nint a, nint b) = (5, 10); nint min = math.min(a, b); nint max = math.max(a, b); nint abs = math.abs(a); nint clamp = math.clamp(abs, min, max); nint sign = math.sign(a); console.writeline($"min = {min}\nmax = {max}\nabs = {abs}"); console.writeline($"clamp = {clamp}\nsign = {sign}"); // divrem variants return a tuple (int quotient, int remainder) = math.divrem(2, 7); console.writeline($"quotient = {quotient}\nremainder = {remainder}"); // output: // sin = 0.9999996829318346 // cos = 0.0007963267107331026 // reciprocal estimate = 0.2 // reciprocal sqrt estimate = 0.4472135954999579 // min = 5 // max = 10 // abs = 5 // clamp = 5 // sign = 1 // quotient = 0 // remainder = 2
collectionsmarshal.getvaluerefornullref
这个是在字典中循环或者修改结可变结构体时用, 可以减少结构的副本复制, 也可以避免字典重复进行哈希计算,这个有点晦涩难懂,有兴趣的可以看看这个
https://github.com/dotnet/runtime/issues/27062
dictionary<int, mystruct> dictionary = new() { { 1, new mystruct { count = 100 } } }; int key = 1; ref mystruct value = ref collectionsmarshal.getvaluerefornullref(dictionary, key); // returns unsafe.nullref<tvalue>() if it doesn't exist; check using unsafe.isnullref(ref value) if (!unsafe.isnullref(ref value)) { console.writeline(value.count); // output: 100 // mutate in-place value.count++; console.writeline(value.count); // output: 101 } struct mystruct { public int count { get; set; } }
configurehostoptions
ihostbuilder 上的新 configurehostoptions api, 可以更简单的配置应用。
public class program { public static void main(string[] args) { createhostbuilder(args).build().run(); } public static ihostbuilder createhostbuilder(string[] args) => host.createdefaultbuilder(args) .configurehostoptions(o => { o.shutdowntimeout = timespan.fromminutes(10); }); }
async scope
.net 6 引入了一种新的createasyncscope方法, 当您处理 iasyncdisposable 的服务时现有的createscope方法会引发异常, 使用 createasyncscope 可以完美解决。
await using var provider = new servicecollection() .addscoped<example>() .buildserviceprovider(); await using (var scope = provider.createasyncscope()) { var example = scope.serviceprovider.getrequiredservice<example>(); } class example : iasyncdisposable { public valuetask disposeasync() => default; }
加密类简化
- decryptcbc
- decryptcfb
- decryptecb
- encryptcbc
- encryptcfb
- encryptecb
static byte[] decrypt(byte[] key, byte[] iv, byte[] ciphertext) { using (aes aes = aes.create()) { aes.key = key; return aes.decryptcbc(ciphertext, iv, paddingmode.pkcs7); } }
到此这篇关于.net 6新增的20个api介绍的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入
-
基于.net EF6 MVC5+WEB Api 的Web系统框架总结(4)-Excel文件读、写操作
-
基于.net EF6 MVC5+WEB Api 的Web系统框架总结(2)-业务项目搭建
-
.Net 6中的PeriodTimer介绍
-
.NET 6新增的20个API介绍
-
使用.Net6中的WebApplication打造最小API
-
ES6新增WeakSet数据结构的详细介绍
-
基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入
-
基于.net EF6 MVC5+WEB Api 的Web系统框架总结(4)-Excel文件读、写操作
-
详细介绍C# 中 ASP.NET Web API 的 ROC