What's new in C# 7.0 (quick preview)
"[Translation] New Features of C# 7" spends a lot of space introducing the 9 new features of C# 7.0. Here I will give a quick introduction to them through examples based on project experience, so that everyone can learn them in a short time. Learn about them within time.
In general, these new features make C# 7.0 easier to write code with functional programming ideas. C# 6.0 has done a lot of work on this road, and C# 7.0 is one step closer!
Expressions everywhere
In C# 6.0, you can use Lambda expressions for member methods and read-only properties. The most frustrating thing at the time was why the set accessor of the property was not supported. Now, not only the set method supports Lambda expressions, but also constructors, destructors, and indexes can be defined in Lambda expressions.
class SomeModel { private string internalValue; public string Value { get => internalValue; set => internalValue = string.IsNullOrWhiteSpace(value) ? null : value; } }
out
Variables
out
Variables are syntax that existed before. C# 7.0 only allows it to declare and use it together to avoid One more line of code. The most direct effect is that two statements can be completed with one expression. Here is a simplified version of the Key
class as an example. This class was used by us early to process the ID value passed in through HTTP Get/Post.
public class Key { public string Value { get; } public Key(string key) { Value = key; } public int IntValue { get { // C# 6.0,需要提前定义 intValue,但不需要初始化 // 虽然 C# 6.0 可以为只读属性使用 Lambda 表达式 // 但这里无法用一个表达式表达出来 int intValue; return int.TryParse(Value, out intValue) ? intValue : 0; } } }
But it’s simple in C# 7
// 注意 out var intValue, // 对于可推导的类型甚至可以用 var 来申明变量 public int IntValue => int.TryParse(Value, out var intValue) ? intValue : 0;
Tuples and destructuring
Friends who have used System.Tuple
must be familiar with itItem1
, Item2
I am deeply offended by such meaningless naming. However, C# 7.0 brings semantic naming, and also simplifies the creation of tuples, no longer requiring Tuple.Create(...)
. In addition, to use the new tuple features and destructuring, you need to introduce the NuGet package System.ValueTuple
.
Install-Package System.ValueTuple
Of course, tuples are often used for methods that return multiple values. Some people also like to use out
parameters for returns, but even though out
variables are now possible, I still don't favor the widespread use of out
parameters.
The following example method is used to return a default time range (a total of 7 days starting from today) for data retrieval.
// 返回类型是一个包含两个元素的元组 (DateTime Begin, DateTime End) GetDefaultDateRange() { var end = DateTime.Today.AddDays(1); var begin = end.AddDays(-7); // 这里使用一对圆括号就创建了一个元组 return (begin, end); }
Call this method to get a tuple. Because the return value specifies the name of each data member when it is defined, obtaining data from the tuple can be semantic. Of course, you can still use Item1
and Item2
.
var range = GetDefaultDateRange(); var begin = range.Begin; // 也可以 begin = range.Item1 var end = range.End; // 也可以 end = range.Item2
The above example can be simplified without using the intermediate variable range
. This uses destructuring
var (begin, end) = GetDefaultDateRange();
The tuple created here is based on the return value. In fact, it is an expression and can create tuples anywhere. The logic of the above example is very simple and can be solved using expressions. The following example demonstrates a non-semantic return type declaration.
// 原来的 (DateTime Begin, DateTime End) 申明也是没问题的 (DateTime, DateTime) GetDefaultDateRange() => (DateTime.Today.AddDays(1).AddDays(-7), DateTime.Today.AddDays(1));
Destructuring method Deconstrct
The destructuring method allows any class (not just tuples) to be destructured according to defined parameters. And the amazing thing is that the destructuring method can be a member method or defined as an extension method.
public class Size { public int Width { get; } public int Height { get; } public int Tall { get; } public Size(int width, int height, int tall) { this.Width = width; this.Height = height; this.Tall = tall; } // 定义成成员方法的解构 public void Deconstruct(out int width, out int height) { width = Width; height = Height; } } public static class SizeExt { // 定义成扩展方法的解构 public static void Deconstruct(this Size size, out int width, out int height, out int tall) { width = size.Width; height = size.Height; tall = size.Tall; } }
The following is the code using destructuring
var size = new Size(1920, 1080, 10); var (w, h) = size; var (x, y, z) = size;
The construction method of transformationSize
Remember that the construction method mentioned earlier can be defined as a Lambda expression Style? Here's a revamp of the Size constructor using tuples and Lambda - I'm already drunk!
public Size(int width, int height, int tall) => (Width, Height, Tall) = (width, height, tall);
Pattern Matching
Pattern matching currently supports is
and switch
. It sounds like a very lofty name, but to put it in a more down-to-earth way, it means judging the type and defining a specific type of reference. If you are interested, you can add some additional judgments.
For is
, it means defining a variable and then initializing it when making a judgment, so the code written like this
// 假设逻辑能保证这里的 v 可能是 string 也 可能是 int string ToString(object v) { if (v is int) { int n = (int) v; return n.ToString("X4"); } else { return (string) n; } }
can be simplified to——Okay , just write it as an expression in one step
string ToString(object v) => (v is int n) ? n.ToString("X4") : (string) v;
Of course you may say that the previous one can also be simplified into an expression - okay, let’s not delve into this issue, okay? I'm just demonstrating pattern matching of
is
.
And the pattern matching in switch
seems to be much more useful, let’s take ToString as an example
static string ToString(object v) { switch (v) { case int n when n > 0xffff: // 判断类型,匹配的情况下再对值进行一个判断 return n.ToString("X8"); case int n: // 判断类型,这里 n 肯定 <= 0xffff return n.ToString("X4"); case bool b: return b ? "ON" : "OFF"; case null: return null; default: return v.ToString(); } }
Pay attention to the first branch above## The usage of #when would be fine.
out and
ref can almost be avoided.
0b prefix, and the other is that it can be used in numerical literals. Use
_ arbitrarily to group numbers. This does not require a majority, just give two examples to understand.
const int MARK_THREE = 0b11; // 0x03 const int LONG_MARK = 0b_1111_1111; // 0xff const double PI = 3.14_1592_6536
局部函数
经常写 JavaScript 的同学肯定会深有体会,局部函数是个好东西。当然它在 C# 中带来的最大好处是将某些代码组织在了一起。我之前在项目中大量使用了 Lambda 来代替局部函数,现在可以直接替换成局部函数了。Labmda 和局部函数虽然多数情况下能做同样的事情,但是它们仍然有一些区别
对于 Lambda,编译器要干的事情比较多。总之呢,就是编译效率要低得多
Lambda 通过委托实现,调用过程比较复杂,局部函数可以直接调用。简单地说就是局部函数执行效率更高
Lambda 必须先定义再使用,局部函数可以定义在使用之后。据说这在对递归算法的支持上会有区别
比较常用的地方是 Enumerator 函数和 async 函数中,因为它们实际都不是立即执行的。
我在项目中多是用来组织代码。局部函数代替只被某一个公共 API 调用的私有函数来组织代码虽然不失为一个简化类结构的好方法,但是把公共 API 函数的函数体拉长。所以很多时候我也会使用内部类来代替某些私有函数来组织代码。这里顺便说一句,我不赞成使用 #region
组织代码。
支持更多 async 返回类型
如果和 JavaScript 中 ES2017 的 async 相比,C# 中的 Task/Task<T> 就比较像 <code>Promise
的角色。不用羡慕 JavaScript 的 async 支持 Promise like,现在 C# 的 async 也支持 Task like 了,只要实现了 GetAwaiter
方法就行。
官方提供了一个 ValueTask
作为示例,可以通过 NuGet 引入:
Install-Package System.Threading.Tasks.Extensions
这个 ValueTask
比较有用的一点就是兼容了数据类型和 Task:
string cache; ValueTask<string> GetData() { return cache == null ? new ValueTask<string>(cache) : new ValueTask<string>(GetRemoteData()); // 局部函数 async Task<string> GetRemoteData() { await Task.Delay(100); return "hello async"; } }
"[Translation] New Features of C# 7" spends a lot of space introducing the 9 new features of C# 7.0. Here I will give a quick introduction to them through examples based on project experience, so that everyone can learn them in a short time. Learn about them within time.
In general, these new features make C# 7.0 easier to write code with functional programming ideas. C# 6.0 has done a lot of work on this road, and C# 7.0 is one step closer!
Expressions everywhere
In C# 6.0, you can use Lambda expressions for member methods and read-only properties. The most frustrating thing at the time was why the set accessor of the property was not supported. Now, not only the set method supports Lambda expressions, but also constructors, destructors, and indexes can be defined in Lambda expressions.
class SomeModel { private string internalValue; public string Value { get => internalValue; set => internalValue = string.IsNullOrWhiteSpace(value) ? null : value; } }
out
Variables
out
Variables are syntax that existed before. C# 7.0 only allows it to declare and use it together to avoid One more line of code. The most direct effect is that two statements can be completed with one expression. Here is a simplified version of the Key
class as an example. This class was used by us early to process the ID value passed in through HTTP Get/Post.
public class Key { public string Value { get; } public Key(string key) { Value = key; } public int IntValue { get { // C# 6.0,需要提前定义 intValue,但不需要初始化 // 虽然 C# 6.0 可以为只读属性使用 Lambda 表达式 // 但这里无法用一个表达式表达出来 int intValue; return int.TryParse(Value, out intValue) ? intValue : 0; } } }
But it’s simple in C# 7
// 注意 out var intValue, // 对于可推导的类型甚至可以用 var 来申明变量 public int IntValue => int.TryParse(Value, out var intValue) ? intValue : 0;
Tuples and destructuring
Friends who have used System.Tuple
must be familiar with itItem1
, Item2
I am deeply offended by such meaningless naming. However, C# 7.0 brings semantic naming, and also simplifies the creation of tuples, no longer requiring Tuple.Create(...)
. In addition, to use the new tuple features and destructuring, you need to introduce the NuGet package System.ValueTuple
.
Install-Package System.ValueTuple
Of course, tuples are often used for methods that return multiple values. Some people also like to use out
parameters for returns, but even though out
variables are now possible, I still don't favor the widespread use of out
parameters.
The following example method is used to return a default time range (a total of 7 days starting from today) for data retrieval.
// 返回类型是一个包含两个元素的元组 (DateTime Begin, DateTime End) GetDefaultDateRange() { var end = DateTime.Today.AddDays(1); var begin = end.AddDays(-7); // 这里使用一对圆括号就创建了一个元组 return (begin, end); }
Call this method to get a tuple. Because the return value specifies the name of each data member when it is defined, obtaining data from the tuple can be semantic. Of course, you can still use Item1
and Item2
.
var range = GetDefaultDateRange(); var begin = range.Begin; // 也可以 begin = range.Item1 var end = range.End; // 也可以 end = range.Item2
The above example can be simplified without using the intermediate variable range
. This uses destructuring
var (begin, end) = GetDefaultDateRange();
The tuple created here is based on the return value. In fact, it is an expression and can create tuples anywhere. The logic of the above example is very simple and can be solved using expressions. The following example demonstrates a non-semantic return type declaration.
// 原来的 (DateTime Begin, DateTime End) 申明也是没问题的 (DateTime, DateTime) GetDefaultDateRange() => (DateTime.Today.AddDays(1).AddDays(-7), DateTime.Today.AddDays(1));
Destructuring method Deconstrct
The destructuring method allows any class (not just tuples) to be destructured according to defined parameters. And the amazing thing is that the destructuring method can be a member method or defined as an extension method.
public class Size { public int Width { get; } public int Height { get; } public int Tall { get; } public Size(int width, int height, int tall) { this.Width = width; this.Height = height; this.Tall = tall; } // 定义成成员方法的解构 public void Deconstruct(out int width, out int height) { width = Width; height = Height; } } public static class SizeExt { // 定义成扩展方法的解构 public static void Deconstruct(this Size size, out int width, out int height, out int tall) { width = size.Width; height = size.Height; tall = size.Tall; } }
The following is the code using destructuring
var size = new Size(1920, 1080, 10); var (w, h) = size; var (x, y, z) = size;
The construction method of transformationSize
Remember that the construction method mentioned earlier can be defined as a Lambda expression Style? Here's a revamp of the Size constructor using tuples and Lambda - I'm already drunk!
public Size(int width, int height, int tall) => (Width, Height, Tall) = (width, height, tall);
Pattern Matching
Pattern matching currently supports is
and switch
. It sounds like a very lofty name, but to put it in a more down-to-earth way, it means judging the type and defining a specific type of reference. If you are interested, you can add some additional judgments.
For is
, it means defining a variable and then initializing it when making a judgment, so the code written like this
// 假设逻辑能保证这里的 v 可能是 string 也 可能是 int string ToString(object v) { if (v is int) { int n = (int) v; return n.ToString("X4"); } else { return (string) n; } }
can be simplified to——Okay , just write it as an expression in one step
string ToString(object v) => (v is int n) ? n.ToString("X4") : (string) v;
Of course you may say that the previous one can also be simplified into an expression - okay, let’s not delve into this issue, okay? I'm just demonstrating pattern matching of
is
.
And the pattern matching in switch
seems to be much more useful, let’s take ToString as an example
static string ToString(object v) { switch (v) { case int n when n > 0xffff: // 判断类型,匹配的情况下再对值进行一个判断 return n.ToString("X8"); case int n: // 判断类型,这里 n 肯定 <= 0xffff return n.ToString("X4"); case bool b: return b ? "ON" : "OFF"; case null: return null; default: return v.ToString(); } }
Pay attention to the first branch above## The usage of #when would be fine.
out and
ref can almost be avoided.
0b prefix, and the other is that it can be used in numerical literals. Use
_ arbitrarily to group numbers. This does not require a majority, just give two examples to understand.
const int MARK_THREE = 0b11; // 0x03 const int LONG_MARK = 0b_1111_1111; // 0xff const double PI = 3.14_1592_6536
局部函数
经常写 JavaScript 的同学肯定会深有体会,局部函数是个好东西。当然它在 C# 中带来的最大好处是将某些代码组织在了一起。我之前在项目中大量使用了 Lambda 来代替局部函数,现在可以直接替换成局部函数了。Labmda 和局部函数虽然多数情况下能做同样的事情,但是它们仍然有一些区别
对于 Lambda,编译器要干的事情比较多。总之呢,就是编译效率要低得多
Lambda 通过委托实现,调用过程比较复杂,局部函数可以直接调用。简单地说就是局部函数执行效率更高
Lambda 必须先定义再使用,局部函数可以定义在使用之后。据说这在对递归算法的支持上会有区别
比较常用的地方是 Enumerator 函数和 async 函数中,因为它们实际都不是立即执行的。
我在项目中多是用来组织代码。局部函数代替只被某一个公共 API 调用的私有函数来组织代码虽然不失为一个简化类结构的好方法,但是把公共 API 函数的函数体拉长。所以很多时候我也会使用内部类来代替某些私有函数来组织代码。这里顺便说一句,我不赞成使用 #region
组织代码。
支持更多 async 返回类型
如果和 JavaScript 中 ES2017 的 async 相比,C# 中的 Task/Task<T> 就比较像 <code>Promise
的角色。不用羡慕 JavaScript 的 async 支持 Promise like,现在 C# 的 async 也支持 Task like 了,只要实现了 GetAwaiter
方法就行。
官方提供了一个 ValueTask
作为示例,可以通过 NuGet 引入:
Install-Package System.Threading.Tasks.Extensions
这个 ValueTask
比较有用的一点就是兼容了数据类型和 Task:
string cache; ValueTask<string> GetData() { return cache == null ? new ValueTask<string>(cache) : new ValueTask<string>(GetRemoteData()); // 局部函数 async Task<string> GetRemoteData() { await Task.Delay(100); return "hello async"; } }
The above is the detailed content of What's new in C# 7.0 (quick preview). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











PHP8.3 released: Overview of new features As technology continues to develop and needs change, programming languages are constantly updated and improved. As a scripting language widely used in web development, PHP has been constantly improving to provide developers with more powerful and efficient tools. The recently released PHP 8.3 version brings many long-awaited new features and improvements. Let’s take a look at an overview of these new features. Initialization of non-null properties In past versions of PHP, if a class property was not explicitly assigned a value, its value

An in-depth analysis of the new features of PHP8 to help you master the latest technology. As time goes by, the PHP programming language has been constantly evolving and improving. The recently released PHP8 version provides developers with many exciting new features and improvements, bringing more convenience and efficiency to our development work. In this article, we will analyze the new features of PHP8 in depth and provide specific code examples to help you better master these latest technologies. JIT compiler PHP8 introduces JIT (Just-In-Time) compilation

New features of php8 include JIT compiler, type deduction, named parameters, union types, properties, error handling improvements, asynchronous programming support, new standard library functions and anonymous class extensions. Detailed introduction: 1. JIT compiler, PHP8 introduces the JIT compiler, which is an important performance improvement. The JIT compiler can compile and optimize some high-frequency execution codes in real time, thereby improving the running speed; 2. Type derivation , PHP8 introduces the type inference function, allowing developers to automatically deduce the type of variables when declaring variables, etc.

[Interpretation of new features of Go language: To make programming more efficient, specific code examples are needed] In recent years, Go language has attracted much attention in the field of software development, and its simple and efficient design concept has attracted more and more developers. As a statically typed programming language, Go language continues to introduce new features to improve development efficiency and simplify the code writing process. This article will provide an in-depth explanation of the latest features of the Go language and discuss how to experience the convenience brought by these new features through specific code examples. Modular development (GoModules) Go language from 1

Overview of the new features of CSS3: How to use CSS3 to achieve transition effects CSS3 is the latest version of CSS. Among the many new features, the most interesting and practical one should be the transition effect. Transition effects can make our pages smoother and more beautiful during interaction, giving users a good visual experience. This article will introduce the basic usage of CSS3 transition effects, with corresponding code examples. transition-property attribute: Specify the CSS property transition effect that needs to be transitioned

Overview of the new features of CSS3: How to use CSS3 to achieve horizontally centered layout In web design and layout, horizontally centered layout is a common requirement. In the past, we often used complex JavaScript or CSS tricks to achieve this. However, CSS3 introduced some new features that make horizontally centered layouts simpler and more flexible. This article will introduce some new features of CSS3 and provide some code examples to demonstrate how to use CSS3 to achieve horizontally centered layout. 1. Use flexbox to layout fle

The new Redis extension introduced in PHP8.1 With the rapid development of the Internet, a large amount of data needs to be stored and processed. In order to improve the efficiency and performance of data processing, caching has become an indispensable part. In PHP development, Redis, as a high-performance key-value storage system, is widely used in caching and data storage scenarios. In order to further improve the experience of using Redis in PHP, PHP8.1 introduces a new Redis extension. This article will introduce the new functions of this extension and provide

The new features of go language are: 1. Go module, used to manage the dependencies of Go language projects; 2. Error handling, adding a new error type error, making error handling more flexible and concise; 3. Context package, used Used to transfer request range values between goroutines; 4. Embedding, that is, one structure can be embedded in another structure; 5. Synchronization package, to better control the synchronization and communication between goroutines; 6. Error value, Better distinguish between different types of errors; 7. Generics allow developers to write more flexibly.
