gpt4 book ai didi

干货来袭! C# 7.0 新特性(VS2017可用)

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 24 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章干货来袭! C# 7.0 新特性(VS2017可用)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前言 。

微软昨天发布了新的VS 2017 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 。

分享一下其实2016年12月就已经公布了的C#7.0的新特性吧,虽然很早就出来了,但咱这IDE不支持啊.. 。

不过在昨天的VS2017中已经完美可以支持使用了. 。

E文好的,移步官方介绍地址:https://docs.microsoft.com/zh-cn/dotnet/articles/csharp/csharp-7 。

先列一下相关的语法

1.out-variables(Out变量) 。

2.Tuples(元组) 。

3.Pattern Matching(匹配模式) 。

4.ref locals and returns (局部变量和引用返回) 。

5.Local Functions (局部函数) 。

6.More expression-bodied members(更多的函数成员的表达式体) 。

7.throw Expressions (异常表达式) 。

8.Generalized async return types (通用异步返回类型) 。

9.Numeric literal syntax improvements(数值文字语法改进) 。

正文 。

1. out-variables(Out变量) 。

以前,我们使用out变量的时候,需要在外部先申明,然后才能传入方法,类似如下

?
1
2
3
string ddd = "" ; //先申明变量
ccc.StringOut( out ddd);
Console.WriteLine(ddd);

在C#7.0中我们可以不必申明,直接在参数传递的同时申明它,如下

?
1
2
3
StringOut( out string ddd); //传递的同时申明
Console.WriteLine(ddd);
Console.ReadLine();

2.Tuples(元组) 。

曾今在.NET4.0中,微软对多个返回值给了我们一个解决方案叫元组,类似代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
static void Main( string [] args)
  {
  var data = GetFullName();
  Console.WriteLine(data.Item1);
  Console.WriteLine(data.Item2);
  Console.WriteLine(data.Item3);
  Console.ReadLine();
}
static Tuple< string , string , string > GetFullName()
{
  return new Tuple< string , string , string >( "a" , "b" , "c" );
}

上面代码展示了一个方法,返回含有3个字符串的元组,然而当我们获取到值,使用的时候 心已经炸了,Item1,Item2,Item3是什么鬼,虽然达到了我们的要求,但是实在不优雅 。

那么,在C#7.0中,微软提供了更优雅的方案:(注意:需要通过nuget引用System.ValueTuple)如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void Main( string [] args)
{
var data=GetFullName();
Console.WriteLine(data.a); //可用命名获取到值
Console.WriteLine(data.b);
Console.WriteLine(data.c);
Console.ReadLine();
 
}
 
 
//方法定义为多个返回值,并命名
private static ( string a, string b, string c) GetFullName()
{
return ( "a" , "b" , "c" );
}

解构元组,有的时候我们不想用var匿名来获取,那么如何获取abc呢?我们可以如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main( string [] args)
{
//定义解构元组
( string a, string b, string c) = GetFullName();
 
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.ReadLine();
 
}
 
 
private static ( string a, string b, string c) GetFullName()
{
return ( "a" , "b" , "c" );
}

3. Pattern Matching(匹配模式) 在C#7.0中,引入了匹配模式的玩法,先举个老栗子.一个object类型,我们想判断他是否为int如果是int我们就加10,然后输出,需要如下

?
1
2
3
4
5
6
7
object a = 1;
if (a is int ) //is判断
{
  int b = ( int )a; //拆
  int d = b+10; //加10
  Console.WriteLine(d); //输出
}

那么在C#7.0中,首先就是对is的一个小扩展,我们只需要这样写就行了,如下

?
1
2
3
4
5
6
object a = 1;
if (a is int c) //这里,判断为int后就直接赋值给c
{
  int d = c + 10;
  Console.WriteLine(d);
}

这样是不是很方便?特别是经常用反射的同志们.. 。

那么问题来了,挖掘机技术哪家强?!(咳咳,呸 开玩笑) 。

其实是,如果有多种类型需要匹配,那怎么办?多个if else?当然没问题,不过,微软爸爸也提供了switch的新玩法,我们来看看,如下

我们定义一个Add的方法,以Object作为参数,返回动态类型 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static dynamic Add( object a)
{
dynamic data;
switch (a)
{
case int b:
  data=b++;
  break ;
case string c:
  data= c + "aaa" ;
  break ;
default :
  data = null ;
  break ;
}
return data;
}

下面运行,传入int类型

?
1
2
3
4
object a = 1;
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

输出如图

干货来袭! C# 7.0 新特性(VS2017可用)

我们传入String类型的参数,代码和输出如下

?
1
2
3
4
object a = "bbbb" ;
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

干货来袭! C# 7.0 新特性(VS2017可用)

通过如上代码,我们就可以体会到switch的新玩法是多么的顺畅和强大了. 。

匹配模式的Case When筛选 。

有的基友就要问了.既然我们可以在Switch里面匹配类型了,那我们能不能顺便筛选一下值?答案当然是肯定的. 。

我们把上面的Switch代码改一下,如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
switch (a)
{
case int b when b < 0:
  data = b + 100;
  break ;
case int b:
  data=b++;
  break ;
case string c:
  data= c + "aaa" ;
  break ;
default :
  data = null ;
  break ;
}

在传入-1试试,看结果如下

干货来袭! C# 7.0 新特性(VS2017可用)

4.ref locals and returns(局部变量和引用返回) 。

已经补上,请移步:C# 7.0之ref locals and returns(局部变量和引用返回) 。

5.Local Functions (局部函数) 。

嗯,这个就有点颠覆..大家都知道,局部变量是指:只在特定过程或函数中可以访问的变量.

那这个局部函数,顾名思义:只在特定的函数中可以访问的函数(妈蛋 好绕口) 。

使用方法如下:  。

?
1
2
3
4
5
6
7
8
9
10
11
public static void DoSomeing()
{
//调用Dosmeing2
int data = Dosmeing2(100, 200);
Console.WriteLine(data);
//定义局部函数,Dosmeing2.
int Dosmeing2( int a, int b)
{
return a + b;
}
}

呃,解释下来 大概就是在DoSomeing中定义了一个DoSomeing2的方法,..在前面调用了一下. 。

(注:值得一提的是局部函数定义在方法的任何位置,都可以在方法内被调用,不用遵循逐行解析的方式)  。

6.More expression-bodied members(更多的函数成员的表达式体) 。

C#6.0中,提供了对于只有一条语句的方法体可以简写成表达式.

如下

?
1
2
3
4
5
6
public void CreateCaCheContext() => new CaCheContext();
//等价于下面的代码
public void CreateCaCheContext()
{
new CaCheContext();
}

但是,并不支持用于构造函数,析构函数,和属性访问器,那么C#7.0就支持了..代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 构造函数的表达式写法
public CaCheContext( string label) => this .Label = label;
 
// 析构函数的表达式写法
~CaCheContext() => Console.Error.WriteLine( "Finalized!" );
 
private string label;
 
// Get/Set属性访问器的表达式写法
public string Label
{
  get => label;
  set => this .label = value ?? "Default label" ;
}

7.throw Expressions (异常表达式) 。

在C#7.0以前,我们想判断一个字符串是否为null,如果为null则抛除异常,我们需要这么写

?
1
2
3
4
5
6
7
8
9
public string IsNull()
{
string a = null ;
if (a == null )
{
throw new Exception( "异常了!" );
}
return a;
}

这样,我们就很不方便,特别是在三元表达式 或者非空表达式中,都无法抛除这个异常,需要写if语句. 。

那么我们在C#7.0中,可以这样

?
1
2
3
4
5
public string IsNull()
{
string a = null ;
return a ?? throw new Exception( "异常了!" );
}

 8.Generalized async return types (通用异步返回类型) 。

嗯,这个,怎么说呢,其实我异步用的较少,所以对这个感觉理解不深刻,还是觉得然并卵,在某些特定的情况下应该是有用的. 。

我就直接翻译官方的原文了,实例代码也是官方的原文. 。

异步方法必须返回 void,Task 或 Task<T>,这次加入了新的ValueTask<T>,来防止异步运行的结果在等待时已可用的情境下,对 Task<T> 进行分配。对于许多示例中设计缓冲的异步场景,这可以大大减少分配的数量并显著地提升性能.

官方的实例展示的主要是意思是:一个数据,在已经缓存的情况下,可以使用ValueTask来返回异步或者同步2种方案 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class CaCheContext
{
public ValueTask< int > CachedFunc()
{
return (cache) ? new ValueTask< int >(cacheResult) : new ValueTask< int >(loadCache());
}
private bool cache = false ;
private int cacheResult;
private async Task< int > loadCache()
{
// simulate async work:
await Task.Delay(5000);
cache = true ;
cacheResult = 100;
return cacheResult;
}
}

调用的代码和结果如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//main方法可不能用async修饰,所以用了委托.
static void Main( string [] args)
{
Action act = async () =>
{
CaCheContext cc = new CaCheContext();
int data = await cc.CachedFunc();
Console.WriteLine(data);
int data2 = await cc.CachedFunc();
Console.WriteLine(data2);
};
// 调用委托
act();
Console.Read();
 
}

上面的代码,我们连续调用了2次,第一次,等待了5秒出现结果.第二次则没有等待直接出现结果和预期的效果一致. 。

 9.Numeric literal syntax improvements(数值文字语法改进) 。

这个就纯粹的是..为了好看了. 。

在C#7.0中,允许数字中出现"_"这个分割符号.来提高可读性,举例如下

?
1
2
3
4
5
6
7
int a = 123_456;
int b = 0xAB_CD_EF;
int c = 123456;
int d = 0xABCDEF;
Console.WriteLine(a==c);
Console.WriteLine(b==d);
//如上代码会显示两个true,在数字中用"_"分隔符不会影响结果,只是为了提高可读性

当然,既然是数字类型的分隔符,那么 decimal, float 和 double  都是可以这样被分割的.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.

原文链接:http://www.cnblogs.com/GuZhenYin/p/6526041.html 。

最后此篇关于干货来袭! C# 7.0 新特性(VS2017可用)的文章就讲到这里了,如果你想了解更多关于干货来袭! C# 7.0 新特性(VS2017可用)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com