C#6.0新特性笔记

Getter专属赋值

可以在构造函数中,给只有get的属性赋初始值。

class Point
{
public int x { get; }
public Point()
{
x = 1;
}
}

自动属性初始化

可以给自动属性,赋初始化值

class Point
{
public int x { get; set; } = 1;
}

全局静态

可以设置全局静态,然后直接写静态类的方法。

using static System.Console;

namespace FxApp
{
internal class Program
{
private static void Main(string[] args)
{
Read();
}
}
}

全局枚举

可以设置全局枚举,然后直接写枚举属性

using static System.ConsoleColor;

namespace FxApp
{
internal class Program
{
private static void Main(string[] args)
{
var color = Red;
}
}
}

字符串插入

可以使用$来进行字符串插入,替代string.format。全局变量或参数都可插入

internal class Program
{
public static int x { get; set; }
private static void Main(string[] args)
{
string text = $"{x},{args}";
}
}

Expression bodied

可以使用箭头表达式来给方法或属性提供表达式体。注意,表达式体不能有括号。

 internal class Program
{
public string Name => "Chenxy";
public int Sum(int x, int y) => x + y;
private static void Main(string[] args)
{
Program po = new Program();
Console.WriteLine(po.Name); //Chenxy
Console.WriteLine(po.Sum(1, 2)); //3
Console.Read();
}
}

索引值初始化

可以给集合赋初始化值

internal class Program
{
IDictionary<int, string> dict = new Dictionary<int, string>()
{
[1] = "first",
[2] = "second"
};
private static void Main(string[] args)
{
Program po = new Program();
foreach (var item in po.dict)
{
Console.WriteLine(item.Value);
}
Console.Read();
}
}

?.运算符

空值运算符,可以简化判断null的工作

public class Point
{
public int x { get; } = 1;
}
internal class Program
{
public static void Main(string[] args)
{
Point po = null;
//C# 5.0 写法
if (po != null)
{
Console.WriteLine(po.x);
}
//C# 6.0 写法
Console.WriteLine(po?.x);
Console.Read();
}
}

nameof表达式

为了防止重构时忘记修改,可以使用nameof来将一个常量和变量绑定。变量改变时,常量随之改变

internal class Program
{
public static void Main(string[] args)
{
string error = string.Empty;
//C# 5.0
Console.WriteLine("error"); //error
//C# 6.0
Console.WriteLine(nameof(error)); //error Console.Read();
}
}

在此代码中,如果改变 error名称,但不修改nameof(error)名称。则会在编译时提示

异常过滤器

可以在try catch中进行判断,来控制是否进入catch。如果hideError为false,则不会进入catch。

public static void Main(string[] args)
{
bool hideError = false;
try
{
throw new Exception();
}
catch (Exception ex) when (hideError)
{
Console.WriteLine("异常已抛出");
} Console.Read();
}

catch和finally中使用await

可以在catch 和 finally中,使用await。

internal class Program
{
public async static void Main(string[] args)
{
HttpClient client = null;
try
{
var result = await client.GetAsync("");
}
catch (Exception ex)
{
var result = await client.GetAsync("");
}
finally
{
var result = await client.GetAsync("");
} Console.Read();
}
}

Visual Studio 2017

https://zhuanlan.zhihu.com/p/25626653

C#7.0新特性笔记

Out

原先代码中,如果使用Out参数,需要预先定义变量。而C#7中,则可以直接在输出参数中定义变量。

我们也可以直接在参数中,定义var隐式变量。

//VS2015
static void Main(string[] args)
{
int x;
OutMethod(out x);
WriteLine($"X:{x}");
Read();
} //VS2017
static void Main(string[] args)
{
OutMethod(out int x);
WriteLine($"X:{x}");
Read();
}

解构

在调用函数中,可以将参数组合封装到一个类的构造函数中。但是无法通过对象解构成各个组成部分。

通过解构函数,则可以完成这个事情。解构函数可以返回对象的具体确定组件。

例如,我们模拟一个参数组合

public class PathInfo {
public string DirectoryName { get; set; }
public string FileName { get; set; }
public string Extension { get; set; }
public PathInfo(string dname, string fname, string extension)
{
DirectoryName = dname;
FileName = fname;
Extension = extension;
}
}

我们需要从nuget加载 System.ValueTuple这样,才可以使用元组进行解构。

我们如果要使用解构,就需要先定义一个解构函数:Desconstruct

public void Deconstruct(out string dname, out string fname, out string extension)
{
dname = DirectoryName;
fname = FileName;
extension = Extension;
}

需要注意的是,必须使用out,名称可以不一样,他是按照参数顺序返回的。

接下来,现在我们使用解构函数来调用。我们展示三种示例,来进行调用测试。

class Program
{
static void Main(string[] args)
{
PathInfo info = new PathInfo("d", "f", "e"); //示例一:参数内声明。也可以使用var
(string dname, string fname, string extension) = info;
WriteLine($"{dname},{fname},{extension}"); //示例二:声明值初始化。分配现有变量
string dname1, fname1, extension1 = null;
(dname1, fname1, extension1) = info;
WriteLine($"{dname1},{fname1},{extension1}"); //示例三:隐式变量声明
var (dname2, fname2, extension2) = info;
WriteLine($"{dname2},{fname2},{extension2}");
Read();
}
}

跟元组类似的写法,会给每个值进行赋值,只要顺序对应即可。

注意:在示例三种,我们在括号外面声明的var,这样括号内的三个变量类型必须一致。

解构函数,要求圆括号内至少有两个输出变量。如果只有一个是不起作用的,例如

(string dname) = info; //这样是不行的。Deconstruct,如果只有一个方法是不行的。

Deconstruct,可以进行重载。使用的时候,会自动找对应的重载方法。

元组

通过元组可以从一个方法中返回多个值。在C#7.0之前,我们会定义输出参数或者对象集合。

我们可以通过两种方式,来定义元祖。

1.不使用参数名,只填写参数类型。这样会返回 Item1,2,3

2.使用参数名,并填写参数类型。这样会返回Item.参数名

3.直接使用参数名。和2一个效果,但是方便一些。

class Program
{
static void Main(string[] args)
{
PathInfo info = new PathInfo(); var item = info.getEmpInfo();
WriteLine($"{item.Item1},{item.Item2},{item.Item3}"); var item2 = info.getEmpInfo2();
WriteLine($"{item2.a},{item2.b},{item2.c}"); var item3 = info.getEmpInfo3();
WriteLine($"{item3.a},{item3.b},{item3.c}"); Read();
}
} public class PathInfo
{
// 不使用参数名,返回Item1,2,3
public (string, string, string) getEmpInfo()
{
return ("a", "b", "c");
}
// 使用参数名,返回定义参数名
public (string a, string b, string c) getEmpInfo2()
{
return ("a", "b", "c");
}
// 使用指定元素
public (string a, string b, string c) getEmpInfo3()
{
return (a: "a", b: "b", c: "c");
}
}

模式匹配

有时候基类会派生一些子类。我们如果要对每个类实施Eject方法。可以使用多个选择来实现。

AS运算符

使用AS运算符转换并赋值

检查结果是否为null

执行Eject操作

IS运算符

使用IS运算符检查类型

转换类型并为其赋值

执行Eject操作

Cast

显示转换赋值

捕捉可能的异常

执行操作

上述这些方法存在的问题都是语法相当冗长,总要为转换的类提供多个语句

具有IS表达式的模式匹配

C#7.0提供模式匹配,用作一种将测试和赋值合并为单个操作方法。

举个例子,我们在C#7以前,进行类型转换如下。我们使用IS运算符

class Program
{
static void Main(string[] args)
{
Eject(new Woman());
Read();
} static void Eject(People peo)
{
if (peo is Woman)
{
Woman wo = (Woman)peo;
wo.Con();
}
}
} class People {} class Woman : People {
public void Con() {
WriteLine("This is Woman");
}
}

可以看出来,我们需要进行 is,然后进行转换。现在我们使用模式匹配来实现上面代码

static void Eject(People peo)
{
if (peo is Woman wo)
{
wo.Con();
}
}

模式匹配将测试和赋值合并成一个操作了。

Switch语句的模式匹配

使用Switch可以在多个可转换的兼容类型之间时更加重要。

如果我们想添加一个附加条件,可以使用when附加在case子句。

static void Eject(People peo)
{
switch (peo)
{
case Woman wo when wo != null:
wo.Con();
break;
case People pe:
break;
default:
break;
}
}

本地函数

C#7.0允许在一个成员内部完全声明本地函数。来替代Action和Func.

本地函数的作用于域,进在周围函数的内部。关于本地函数有以下几个注意点

1.不允许修饰符

2.不支持重载

3.本地函数可以访问所有变量,包括局部变量

4.本地函数存在整个方法范围内,声明不分前后

bool IsPalindrome(string text)
{
if (string.IsNullOrWhiteSpace(text)) return false;
bool LocalIsPalindrome(string target)
{
target = target.Trim(); // Start by removing any surrounding whitespace.
if (target.Length <= 1) return true;
else
{
return char.ToLower(target[0]) ==
char.ToLower(target[target.Length - 1]) &&
LocalIsPalindrome(
target.Substring(1, target.Length - 2));
}
}
return LocalIsPalindrome(text);
}

通过引用返回

通过ref可以将参数传递给函数来进行更新。

C#7.0除了ref参数外,还可以通过函数返回一个引用。

class Program
{
static void Main(string[] args)
{
int[] result = { 1, 2, 3 };
ref int a = ref Find(result);
a += 1;
WriteLine(result[0]);
Read();
} static ref int Find(int[] sum)
{
return ref sum[0];
}
}

文本改进

C#7.0可以通过下划线来提高可读性。可以放在二进制、十进制、十六进制数字的任意位置

long LargestSquareNumberUsingAllDigits =
0b0010_0100_1000_1111_0110_1101_1100_0010_0100; // 9,814,072,356
long MaxInt64 { get; } =
9_223_372_036_854_775_807; // Equivalent to long.MaxValue

Throw表达式

可以在表达式中,直接抛出异常

public string getEmpInfo( string EmpName)
{
string[] empArr = EmpName.Split(",");
return (empArr.Length > 0) ? empArr[0] : throw new Exception("Emp Info Not exist");
}

异步返回类型

编译器不限制异步方法必须返回 void、Task、Task<T>。

任何可以继承 GetAwaiter   方法的都可以进行返回。

但是,此方法我验证不通过。故此暂时不考虑这个特性。

Expression bodied 增强

C#7.0里面把箭头函数表达式,进行了增强。

我们可以直接在构造函数、析构函数中使用

public class Point
{
public Point() => WriteLine("构造"); ~Point() => WriteLine("释放");
}

$

C#新特性记录的更多相关文章

  1. ES2020新特性记录

    1.可选链操作符 // oldlet ret = obj && obj.first && obj.first.second// newlet ret = obj?.fi ...

  2. C# 9.0 新特性之只读属性和记录

    阅读本文大概需要 2 分钟. 大家好,这是 C# 9.0 新特性系列的第 4 篇文章. 熟悉函数式编程的童鞋一定对"只读"这个词不陌生.为了保证代码块自身的"纯洁&quo ...

  3. 【c#】6.0与7.0新特性介绍记录

    c#发展史 引用地址:https://www.cnblogs.com/ShaYeBlog/p/3661424.html 6.0新特性 1.字符串拼接优化 语法格式:$”string {参数}” 解释: ...

  4. SQL Server 2014 新特性——内存数据库

    SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...

  5. 跨平台的 .NET 运行环境 Mono 3.2 新特性

    Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...

  6. 谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 撰写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源 ...

  7. MySQL5.6 GTID新特性实践

    MySQL5.6 GTID新特性实践 GTID简介 搭建 实验一:如果slave所需要事务对应的GTID在master上已经被purge了 实验二:忽略purged的部分,强行同步 本文将简单介绍基于 ...

  8. Sql Server 2012新特性 Online添加非空栏位.

    我们都知道,Sql Server在一个数据量巨大的表中添加一个非空栏位是比较费心的,缺乏经验的DBA或是开发人员甚至可能鲁莽地直接添加导致阻塞相应业务,甚至可能因为资源欠缺造成实例的全局问题.当然这都 ...

  9. HTML5_01之表单新特性

    1.WebStorm快捷键: Ctrl+Alt+(向下方向键):快速复制当前行 Alt+(向上/下方向键):移动当前行 Ctrl+D:删除当前行 Ctrl+/:快速(取消)注释当前行 Ctrl+Alt ...

随机推荐

  1. UVa 1262 - Password(解码)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 7、springmvc的自动配置

    1.springmvc的自动配置 文档:https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot ...

  3. JDBC(2)Statement

    Statement: 用于执行SQL语句的对象 通过Connection的createStatement()方法得到一个Statement对象 只有在获得了Statement对象之后才能执行SQL对象 ...

  4. ASP.NET Web API编程——文件下载

    断点续传基本原理 HTTP协议中与断点续传相关的HTTP头为:Range和Content-Range标头,断点续传实现流程: 1)客户端请求下载一个文件,文件的总长度为n:已经下载了一部分文件,长度为 ...

  5. 使用Nginx 做负载均衡

    Nginx可以作为一个非常高效的负载均衡系统,通过分发HTTP请求到多个应用服务器来提高整个系统的吞吐量,性能和可用性. 负载均衡的算法/机制 下面是Nginx支持的机制 轮询机制 轮询算法 最少连接 ...

  6. Coursera 机器学习基石 第4讲 学习的可行性

    这一节讲述的是机器学习的核心.根本性问题——学习的可行性.学过机器学习的我们都知道,要衡量一个机器学习算法是否具有学习能力,看的不是这个模型在已有的训练数据集上的表现如何,而是这个模型在训练数据外的数 ...

  7. MacType 文字之美 – 让 Windows 字体更漂亮

    苹果的Mac系统总能让人眼前一亮,除了其精美的软件界面设计外,最重要是其文字显示效果(渲染方式)比 Windows 更加清晰锐利,阅读起来更加舒服.于是就有高手开发了一款叫 GDI++ 的字体渲染引擎 ...

  8. Android客户端与服务器端通过DES加密认证

    转载地址:http://blog.csdn.net/spring21st/article/details/6730283 由于Android应用没有像web开发中的session机制,所以采用PHPS ...

  9. Google 和 Baidu 常用的搜索技巧

    Google 常用的搜索技巧 1. 精确搜索:双引号 精确搜索,就是在你要搜索的词上,加上双引号,这个Google搜索引擎,就会完全的匹配你所要的词 2. 站内搜索:site 这是一个比较常用的搜索方 ...

  10. 手机端app开发初识

    1.所需软件说明 百度云下载链接: https://pan.baidu.com/s/1-TEQZP9QbJSlGSYedyAUFw密码: 2z8l 或者官方链接: Hbuilder:http://ww ...