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. ASP.NET Web API编程——文件下载

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

  2. PAT——1004. 成绩排名

    原题目:https://www.patest.cn/contests/pat-b-practise/1004 读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每 ...

  3. 【题解】洛谷P1879 [USACO06NOV] Corn Fields(状压DP)

    洛谷P1879:https://www.luogu.org/problemnew/show/P1879 思路 把题目翻译成人话 在n*m的棋盘 每个格子不是0就是1 1表示可以种 0表示不能种 相邻的 ...

  4. ORA-04044: 此处不允许过程, 函数, 程序包或类型和

    用Orale代码建表时,出现 SQL> comment on column SCORE.cno 2 is '学号(外键)';comment on column SCORE.cno is '学号( ...

  5. 打印iframe某区域

    <a href="#" onClick="parent.iframe名字.focus();window.print();">打印</a>

  6. RBG颜色对照表:有网址

    RBG颜色对照表 大家都懂的RBG颜色对照表,想做一个有个性和美观的网页,风格是必须要有的,那么多姿多彩的颜色必然是装饰网页的一簇鲜花,为了方便查找比对颜色,就做了这个 网址为: http://too ...

  7. Unity 游戏框架搭建 (二十三) 重构小工具 Platform

    在日常开发中,我们经常遇到或者写出这样的代码 var sTrAngeNamingVariable = "a variable"; #if UNITY_IOS || UNITY_AN ...

  8. Ubuntu下Zabbix结合percona监控mysql数据

    按道理来说zabbix就自带的MySQL插件来监控mysql数据库,但是你会发现,自带的mysql监控项是很少的,根本满足不了公司的需求.由于它本身自带的模板太过简单了,所以需要做更详细的监控,而pe ...

  9. 转:Java中的cas

    引自:https://blog.csdn.net/mmoren/article/details/79185862 本篇的思路是先阐明无锁执行者CAS的核心算法原理然后分析Java执行CAS的实践者Un ...

  10. JS原生评分组件

    JS原生评分组件 <html> <head> <meta http-equiv="Content-Type" content="text/h ...