创网中国的网站,wordpress paypal插件,微信朋友圈营销文案,网站空间大小Dotnet 6.0 就要来了#xff0c;这会是一个绝对值得拥有的版本。了解一下#xff1f;最近在研究 Dotnet 6.0 C# 10#xff0c;一个字 - 爽#xff01;下面#xff0c;分享一下新的一些特性给大家。一、编程语言方面编程语言升到 C# 10#xff0c;新东西不少。1. 属… Dotnet 6.0 就要来了这会是一个绝对值得拥有的版本。了解一下 最近在研究 Dotnet 6.0 C# 10一个字 - 爽下面分享一下新的一些特性给大家。一、编程语言方面编程语言升到 C# 10新东西不少。1. 属性的 required看一个简单的例子public class User
{public string name { get; set; }public DateTime dateOfBirth { get; set; }
}
假设我们希望 dateOfBirth 字段必须输入。在 C# 9.0 之前其实我们没有更好的办法。比方var myUser new User()
{name WangPlus,
}
这样写编译器是不会给出任何提醒或警告的。因此我们需要在各个使用的地方加上字段赋值的检查。 而在最新的语言中对于这样的需求增加了一个 required 属性。看代码public class User
{public string name { get; set; }public required DateTime dateOfBirth { get; set; }
}
这时候当你实例化 User而没有给 dateOfBirth 赋值时编译器会直接扔出异常。在我写这个文章的同时刚刚发现这个特性从最新的 preview 里给移除了似乎微软想把这个放到 C# 11中。目前论坛上吵翻了。我们静待一下结果。2. 属性的 field在大多数情况下我们定义一个类会采用这种方式public class User
{public string name { get; set; }public DateTime dateOfBirth { get; set; }
}
但有时候因为一些需要需要提前实例化或者实例化时需要进行某些处理。比方上面的类我们只想要 dateOfBirth 的日期部分我们会把类做成这个样子public class User
{public string name { get; set; }private DateTime _dateOfBirth;public DateTime dateOfBirth { get{return _dateOfBirth;}set{_dateOfBirth value.Date;}}
}
当然习惯了也没什么麻烦的。不过我们知道_dateOfBirth 这个私有属性其实是一个中间数据对外没有用处但会占用实例资源。 现在有了一个中间属性叫 field。代码会变成这样public class User
{public string name { get; set; }public DateTime dateOfBirth { get; set field value.Date; }
}
嗯嗯可读性就高了不少。3. 匿名对象的 with匿名对象的出现给我们带来了相当多的方便。在类中不需要对外输出的结构化数据都可以做成匿名对象而不需要预先定义一个数据对象。看代码var myUser new { name WangPlus, gender Male };
嗯。真的很方便。不过也有不方便的地方就是匿名对象的传递。比方我们想创建另一个对象 myUser1属性还是这些仅仅需要改变几个属性的值怎么办在以前没有别的办法只能重写一个var myUser1 new { name WangPlus1, gender Male };
/** 或者 **/
var myUser1 new { name WangPlus1, gender myUser.gender };
可以想象如果这个匿名对象字段很多的话就会麻烦的不要不要的。 现在有了 with这个事情就简单了var myUser1 myUser with { name WangPlus1 };
注意这个写法不是把 myUser 里的属性改了而是新生成了一个实例并传递了 myUser 的全部属性和值到新实例 myUser1然后才是把一些属性的值改成新的值。4. 非空参数检查在我们写一个方法时成熟的程序员都会做参数的非空检查public string FormatName( string name )
{if( string.isNullOrEmpty( name ) )return ERROR;/** ... **/
}
public string FormatUser( User user )
{if( user null )return ERROR;/** ... **/
}
做法很正确但很麻烦一个套路性的东西却要不停的写。现在有了一个神参数没错就是叹号。写法是这样public string FormatName( string name! )
{/** ... **/
}
public string FormatUser( User user! )
{/** ... **/
}
加上 ! 后执行中程序会自动检查参数的非空状态如果出现 null会抛出 ArgumentNullExceptions。5. global using这是最爽的一个特性。以前我们写代码每个文件前边都有无数个 using而且很多 using 都是重复的。现在C# 10 提供了一个 global 关键字。从此using 变成了global using System;
global using System.Collections.Generic;
global using System.Threading.Tasks;
系统会识别 global using 后边的内容会应用于整个项目。因此在其它文件中如果需要使用时可以不写对应的 using 直接写代码即可。再因此可以把所有的 global using 放到一个单独的文件中而在其它文件中不需要再做 using 引用。同时如果已经存在 global using而你的文件中又写了同样库的 using系统会扔出一个警告。6. 文件级的命名空间 namespace这个特性好像没有省了多少事。不过也算是一个变化。以前我们做代码时是这样namespace MyNamespace
{public class User{public void User() {//...Method implementation}}
}
外部调用时就这么写var obj new MyNamespace.User();
/** 或者 **/
using MyNamespace;
var obj new User();
现在命令空间的定义改成了namespace MyNamespace;
public class User
{public void User() {//...Method implementation}
}
这样写清爽了一些缩进的层次也少了一层。当然调用还是一样的。二、API方面API 方面就更多了。在社区里不停的会有新的 API 爆出来。我就选一些自己感觉有用的来说。1. 非流式读写文件流式读写经常会涉及到中间流资源浪费不说写起来也麻烦。现在可以直接用底层 IO 来读写。方法加到了 File 类中。var handler File.OpenHandle(abc.txt);
var length RandomAccess.GetLength(handler);
2. 强随机数我们知道以前的随机数 Random 类是弱随机数来自于一个算法并不能做到真正的随机。生成的随机数序列取决于种子相同的种子会产生相同的随机数序列。所以为了取到不同的随机数序列我们一般这么写var rand new Random( (int)DateTime.Now.Ticks );
当然一般这样也就够了。但总有特殊的需要真正的随机数即强随机数。Dotnet 6.0 里提供了一个 RandomNumberGenerator 的类。byte[] bytes RandomNumberGenerator.GetBytes(200);
int randomInt RandomNumberGenerator.GetInt32(0, 10000);
另外需要注意一下这个类不在 System 空间下而在 System.Security.Cryptography 里。3. 多任务的异步 Parallel.ForEachAsync在多任务中以前只有一个 Parallel.ForEach 的方法用来同步执行。这回终于把异步方法 Parallel.ForEachAsync 加进来了足以可见微软在异步方面的深化决心。写法还是我们很熟悉的方式这个切换很容易var urls new []
{https://test1.com,https://test2.com
};
var client new HttpClient();
await Parallel.ForEachAsync(urls, async (url, token)
{HttpResponseMessage response await client.GetAsync(url);
});
4. 定时中止异步这也是个不错的 API。以前当 await 异步进程时如果这个进程长时间结束不了我们只能通过 CancellationToken 来结束。现在我们有了另一个方式可以设置一个时间以 Timeout 的方式结束这个异步进程。Task someTask SomeLongRunningTaskAsync();
await someTask.WaitAsync(TimeSpan.FromSeconds(10));
如果你写过 CancellationToken 结束异步的代码就知道这个 WaitAsync 有多好。5. ThrowIfNull这个东西其实跟上面判断参数是否为空是一件事。当我们在参数据后面加 来进行为空判断时实际就是执行的这一句public string FormatUser( User user )
{ArgumentNullException.ThrowIfNull( user );
}
如果对象为空就抛出一个 ArgumentNullException。6. 使用直接内存在以前使用 unsafe 内存 malloc 时都是在堆上分配空间。现在有了一个在直接内存分配空间的方法using System.Runtime.InteropServices;
unsafe
{byte* buffer (byte*)NativeMemory.Alloc(128);NativeMemory.Free(buffer);
}
做嵌入式开发有福了。另外通常使用非托管内容需要进行大小对齐。所谓对齐就是分配的空间的大小需要是 2 的整指数。通常大家就是算好直接硬写现在也有了更灵活的方式using System.Numerics;uint bufferSize 211;
if (!BitOperations.IsPow2(bufferSize))
{bufferSize BitOperations.RoundUpToPowerOf2(bufferSize);
}
给一个空间如果空间大小不是 2 的整指数就找比这个数大的 2 的整指数。又省事了。7. 新的计时器好多文章都把这个计时器称为 Modern Timer足以可见它的好。好在哪这是一个异步的计时器。以前的计时器 Timer不管是 System.Timers 下的还是 System.Threading 下的或是 System.Windows.Forms 下的都是同步的计时器需要用 Tick 的事件绑定来实现回调。这个方式让这个计时器十分依赖上级对象的生命周期以至于在 UI 编程中需要用 Invoke 来引入回调响应。现在这个就简单很多了var timer new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync())
{/** ... **/
}
这个写法看着就舒服。 写了很多但实际上也只是冰山的一小角。想了解全部的内容可以没事去泡泡 Dotnet 的社区每天都有新东西每天都有惊喜。喜欢就来个三连让更多人因你而受益