C#新特性记录
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#新特性记录的更多相关文章
- ES2020新特性记录
1.可选链操作符 // oldlet ret = obj && obj.first && obj.first.second// newlet ret = obj?.fi ...
- C# 9.0 新特性之只读属性和记录
阅读本文大概需要 2 分钟. 大家好,这是 C# 9.0 新特性系列的第 4 篇文章. 熟悉函数式编程的童鞋一定对"只读"这个词不陌生.为了保证代码块自身的"纯洁&quo ...
- 【c#】6.0与7.0新特性介绍记录
c#发展史 引用地址:https://www.cnblogs.com/ShaYeBlog/p/3661424.html 6.0新特性 1.字符串拼接优化 语法格式:$”string {参数}” 解释: ...
- SQL Server 2014 新特性——内存数据库
SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...
- 跨平台的 .NET 运行环境 Mono 3.2 新特性
Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...
- 谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 撰写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源 ...
- MySQL5.6 GTID新特性实践
MySQL5.6 GTID新特性实践 GTID简介 搭建 实验一:如果slave所需要事务对应的GTID在master上已经被purge了 实验二:忽略purged的部分,强行同步 本文将简单介绍基于 ...
- Sql Server 2012新特性 Online添加非空栏位.
我们都知道,Sql Server在一个数据量巨大的表中添加一个非空栏位是比较费心的,缺乏经验的DBA或是开发人员甚至可能鲁莽地直接添加导致阻塞相应业务,甚至可能因为资源欠缺造成实例的全局问题.当然这都 ...
- HTML5_01之表单新特性
1.WebStorm快捷键: Ctrl+Alt+(向下方向键):快速复制当前行 Alt+(向上/下方向键):移动当前行 Ctrl+D:删除当前行 Ctrl+/:快速(取消)注释当前行 Ctrl+Alt ...
随机推荐
- BZOJ3196:二逼平衡树(线段树套Splay)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
- ASP.NET SingalR 点对点聊天实现思路总结
前一段时间写了一个简单的聊天室,是群聊的方式.博客地址:http://www.cnblogs.com/panzi/p/4980346.html.还有一种需求就是常见的尤其是培训机构的主页面,经常会有1 ...
- Linq 表达
Lambda 简单了解 //Lambda //匿名方法 //delegate (Student s) { return s.Age > 12 && s.Age < 20; ...
- 关于结构体占用空间大小总结(#pragma pack的使用)
关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的.这道题是这样的: 在32位机器上,下面的代码中 class A { publi ...
- ZXing.net 生成和解析二维码
nuget引用zxing.net包 public partial class Form1 : Form { public Form1() { InitializeComponent(); } priv ...
- MyEclipse中好用的快捷键汇总整理
MyEclipse中常用的快捷键有很多,合理的使用其中一些快捷键组合,可以有效提高开发的效率和质量. 1.Ctrl + Shift + R:打开资源.可以查找并打开工作区中任何一个文件,且支持使用通配 ...
- ASP.NET MVC4.0 后台获取不大前台传来的file
<td>选择图片</td> <td> <input type="file" id="uploadImg" name=& ...
- 常用的JavaScript设计模式(一)Constructor(构造器)模式
在es6中,新增了一个语法糖--class,可以说是为JavaScript引入了类的概念.而在传统的JavaScript中,则是通过构造器生成实例对象的. JavaScript支持特殊的constru ...
- 网站http配置https -- 阿里云 nginx
通过阿里云领取免费证书可将网站配置为https 步骤为下: 登陆阿里云点击sll证书,然后点击购买证书 选择免费的 然后立即购买 购买后会让你填写一些域名信息 然后提交签发证书 签发后点击下方下载 选 ...
- laravel form 表单提交
form表单需要加token,不然会出现419错误,csrf_token不用自己生成,放进去就行,laravel自己会生成 路由: 控制器生成一个: