一小时学会C# 6

c# 6已经出来有一段时间了,今天咱们就详细地看一下这些新的特性。编程

1、字符串插值 (String Interpolation)

C# 6以前咱们拼接字符串时须要这样c#

var Name = "Jack";
 var results = "Hello" + Name;

或者数组

var Name = "Jack";
 var results = string.Format("Hello {0}", Name);

可是C#6里咱们就可使用新的字符串插值特性函数

var Name = "Jack";
  var results = $"Hello {Name}";

上面只是一个简单的例子,想一想若是有多个值要替换的话,用C#6的这个新特性,代码就会大大减少,并且可读性比起以前大大加强this

Person p = new Person {FirstName = "Jack", LastName = "Wang", Age = 100};
 var results = string.Format("First Name: {0} LastName: {1} Age: { 2} ", p.FirstName, p.LastName, p.Age);

有了字符串插值后:spa

var results = $"First Name: {p.FirstName} LastName: {p.LastName} Age: {p.Age}";

字符串插值不光是能够插简单的字符串,还能够直接插入代码code

Console.WriteLine($"Jack is saying { new Tools().SayHello() }");

 var info = $"Your discount is {await GetDiscount()}";

那么如何处理多语言呢?orm

咱们可使用 IFormattable对象

下面的代码如何实现多语言?索引

Double remain = 2000.5; 
 var results= $"your money is {remain:C}";  

# 输出 your money is $2,000.50

使用IFormattable 多语言

class Program
{
    static void Main(string[] args)
    {

        Double remain = 2000.5; 

       var results= ChineseText($"your money is {remain:C}");

        Console.WriteLine(results);
        Console.Read();
    }

    public static string ChineseText(IFormattable formattable)
    {
        return formattable.ToString(null, new CultureInfo("zh-cn"));
    }
}

# 输出  your money is ¥2,000.50

2、空操做符 ( ?. )

C# 6添加了一个 ?. 操做符,当一个对象或者属性职为空时直接返回null, 就再也不继续执行后面的代码,在以前咱们的代码里常常出现 NullException, 因此咱们就须要加不少Null的判断,好比

if (user != null && user.Project != null && user.Project.Tasks != null && user.Project.Tasks.Count > 0)
 {
   Console.WriteLine(user.Project.Tasks.First().Name);
 }

如今咱们能够不用写 IF 直接写成以下这样

Console.WriteLine(user?.Project?.Tasks?.First()?.Name);

这个?. 特性不光是能够用于取值,也能够用于方法调用,若是对象为空将不进行任何操做,下面的代码不会报错,也不会有任何输出。

class Program
{
    static void Main(string[] args)
    {
        User user = null;
        user?.SayHello();
        Console.Read();
    }
}

public class User
{
    public void SayHello()
    {
        Console.WriteLine("Ha Ha");
    }
}

还能够用于数组的索引器

class Program
{
    static void Main(string[] args)
    {
        User[] users = null;

        List<User> listUsers = null;

        // Console.WriteLine(users[1]?.Name); // 报错
        // Console.WriteLine(listUsers[1]?.Name); //报错

        Console.WriteLine(users?[1].Name); // 正常
        Console.WriteLine(listUsers?[1].Name); // 正常

        Console.ReadLine();
    }
}

注意: 上面的代码虽然可让咱们少些不少代码,并且也减小了空异常,可是咱们却须要当心使用,由于有的时候咱们确实是须要抛出空异常,那么使用这个特性反而隐藏了Bug

3、 NameOf

过去,咱们有不少的地方须要些硬字符串,致使重构比较困难,并且一旦敲错字母很难察觉出来,好比

if (role == "admin")
{
}

WPF 也常常有这样的代码

public string Name
{
  get { return name; }
  set
  {
      name= value;
      RaisePropertyChanged("Name");
  }
}

如今有了C#6 NameOf后,咱们能够这样

public string Name
{
  get { return name; }
  set
  {
      name= value;
      RaisePropertyChanged(NameOf(Name));
  }
}

  static void Main(string[] args)
    {
        Console.WriteLine(nameof(User.Name)); //  output: Name
        Console.WriteLine(nameof(System.Linq)); // output: Linq
        Console.WriteLine(nameof(List<User>)); // output: List
        Console.ReadLine();
    }

注意: NameOf只会返回Member的字符串,若是前面有对象或者命名空间,NameOf只会返回 . 的最后一部分, 另外NameOf有不少状况是不支持的,好比方法,关键字,对象的实例以及字符串和表达式

4、在Catch和Finally里使用Await

在以前的版本里,C#开发团队认为在Catch和Finally里使用Await是不可能,而如今他们在C#6里实现了它。

Resource res = null;
        try
        {
            res = await Resource.OpenAsync(); // You could always do this.  
        }
        catch (ResourceException e)
        {
            await Resource.LogAsync(res, e); // Now you can do this … 
        } 
        finally
        {
            if (res != null) await res.CloseAsync(); // … and this.
        }

5、表达式方法体

一句话的方法体能够直接写成箭头函数,而再也不须要大括号

class Program
 {
    private static string SayHello() => "Hello World";
    private static string JackSayHello() => $"Jack {SayHello()}";

    static void Main(string[] args)
    {
        Console.WriteLine(SayHello());
        Console.WriteLine(JackSayHello());
        
        Console.ReadLine();
    }
}

6、自动属性初始化器

以前咱们须要赋初始化值,通常须要这样

public class Person
{
    public int Age { get; set; }

    public Person()
    {
        Age = 100;
    }
}

可是C# 6的新特性里咱们这样赋值

public class Person
{
    public int Age { get; set; } = 100;
}

7、只读自动属性

C# 1里咱们能够这样实现只读属性

public class Person
{
    private int age=100;

    public int Age
    {
        get { return age; }
    }
}

可是当咱们有自动属性时,咱们没办法实行只读属性,由于自动属性不支持readonly关键字,因此咱们只能缩小访问权限

public class Person
{
    public  int Age { get; private set; }
   
}

可是 C#6里咱们能够实现readonly的自动属性了

public class Person
{
    public int Age { get; } = 100;
}

8、异常过滤器 Exception Filter

static void Main(string[] args)
    {

        try
        {
            throw  new ArgumentException("Age");
        }
        catch (ArgumentException argumentException) when( argumentException.Message.Equals("Name"))
        {
            throw  new ArgumentException("Name Exception");

        }

        catch (ArgumentException argumentException) when( argumentException.Message.Equals("Age"))
        {
            throw new Exception("not handle");
            
        }
        catch  (Exception e)
        {
            
            throw;
        }
    }

在以前,一种异常只能被Catch一次,如今有了Filter后能够对相同的异常进行过滤,至于有什么用,那就是见仁见智了,我以为上面的例子,定义两个具体的异常 NameArgumentException 和AgeArgumentException代码更易读。

9、 Index 初始化器

这个主要是用在Dictionary上,至于有什么用,我目前没感受到有一点用处,谁能知道很好的使用场景,欢迎补充:

var names = new Dictionary<int, string>
        {
            [1] = "Jack",
            [2] = "Alex",
            [3] = "Eric",
            [4] = "Jo"
        };

        foreach (var item in names)
        {
            Console.WriteLine($"{item.Key} = {item.Value}");
        }

10、using 静态类的方法可使用 static using

这个功能在我看来,一样是很没有用的功能,也为去掉前缀有的时候咱们不知道这个是来自哪里的,并且若是有一个同名方法不知道具体用哪一个,固然经证明是使用类自己的覆盖,可是容易搞混不是吗?

using System;
using static System.Math;
namespace CSharp6NewFeatures
 {
  class Program
  {
      static void Main(string[] args)
    {
        Console.WriteLine(Log10(5)+PI);
    }
  }
}

总结

上面一到八我认为都是比较有用的新特性,后面的几个我以为用处不大,固然若是找到合适的使用场景应该有用,欢迎你们补充。

最后,祝你们编程愉快。

相关文章
相关标签/搜索