[聚合文章] 【又见C#】C# 7 新特性

c# 2017-07-11 19 阅读

新特性(原文地址)

out参数

if (!int.TryParse(input, out var result)){    
    Console.Write(result);
}

C# 7 之前:

var result = 0;
if (!int.TryParse(input, out result)){    
    Console.Write(result);
}

元组

匿名元组: var sex = ('male', 'female');
命名元组:var sex = (male: 1, female: 0);
分组赋值:(string male, string famale) = (1, 0);--顺序对应
分组赋值的命名元组:(string male, string famale) = (male: 1, female: 0);--名称对应
当需要一组属性的时候,不需要再专门为此定义一个structclass
C# 4中有一个元组概念,在那个版本是一个泛型类,类似于数组结构,一维最多8个元素,但是可以嵌套,所以理论上元素个数可以达到计算机的临界值

此数据结构类似于python中的元组,但功能远弱于python,比如python中的元组可以很方便的排序&分组&截取&统计。
PS:如果IDE不支持元组,使用Nuget下载System.ValueTuple

模式匹配

目前支持两种:isswitch
is:在之前版本我们这样使用if(instance is Type){},这是基于对象类型的判断。该版本增加了对象成员的类型判断

`if(item is int val){}`:类型判断并声明变量 `val`
switch(item){
    case 0:
        break;
    case int val:
        sum += val;
        break;
    case YourClassName instance:
        sum += instance.num1 * instance.num2;
        break;
    case IEnumerable<object> subList when subList.Any():
        sum += DiceSum5(subList);
        break;
    case IEnumerable<object> subList:
        break;
    case null:
        break;
    default:
        throw new InvalidOperationException("unknown item type");
}

本地方法

即方法嵌套

public Task<string> PerformLongRunningWork(string address, int index)
{
    return longRunningWorkImplementation();

    async Task<string> longRunningWorkImplementation()
    {
        var interimResult = await FirstWork(address);
        var secondResult = await SecondStep(index);
        return $"The results are {interimResult} and {secondResult}. Enjoy.";
    }
}

体表达式增加

C#6新特性中新增了体表达式这一特性,只作用于属性和方法。在该版本中支持了更多的成员类型,constructors, finalizers, get, set

// Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;

// Expression-bodied finalizer
~ExpressionMembersExample() => Console.Error.WriteLine("Finalized!");

private string label;

// Expression-bodied get / set accessors.
public string Label
{
    get => label;
    set => this.label = value ?? "Default label";
}

Throw表达式

在之前版本,Throw都是被当成一个语句使用的。在该版本可以用作表达式

public string Name
{
    get => name;
    set => name = value ?? 
        throw new ArgumentNullException(paramName: nameof(value), message: "New name must not be null");
}

当然如果匹配到throw表达式,依旧还是会抛出异常

ValueTask

异步方法返回值有Task,Task<T>,void,该版本新增了一种返回类型 ValueType

public async ValueTask<int> Func()
{
    await Task.Delay(100);
    return 5;
}

如果返回Task<T>,你需要额外的对象分配操作。使用ValueTask则不用
PS:如果IDE不支持ValueTask,使用Nuget下载System.Threading.Tasks.Extensions

数值字面量语法提升

二进制字面值(binary literals), 数位分隔符(digit separators)
用二进制字面值表示十进制数值:int num = 0b0001;
需要以 0b打头
当数字过长时候,可读性降低。这时候可以加入数位分隔符:public const long BillionsAndBillions = 100_000_000_000;
数位分隔符用 _

Ref

public static ref int Find3(int[,] matrix, Func<int, bool> predicate)
{
    for (int i = 0; i < matrix.GetLength(0); i++)
        for (int j = 0; j < matrix.GetLength(1); j++)
            if (predicate(matrix[i, j]))
                return ref matrix[i, j];
    throw new InvalidOperationException("Not found");
}

ref var item = ref MatrixSearch.Find3(matrix, (val) => val == 42);

PS:没怎么碰到过这种应用场景

在该版本中除了元组比较惊艳,其他的基本无感。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。