This is the 22nd day of my participation in Gwen Challenge

1. String Interpolation

Before C# 6 we needed this for concatenating strings

 var Name = "Jack";
 var results = "Hello" + Name;
Copy the code

or

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

But in C#6 we can use the new string interpolation feature

  var Name = "Jack";
  var results = $"Hello {Name}";
Copy the code

As a simple example, consider that if you have multiple values to replace, the code is much smaller and much more readable with this new C#6 feature

 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);
Copy the code

With string interpolation:

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

String interpolation is not just about inserting simple strings, but also inserting code directly

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

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

So how do you deal with multiple languages?

We can use IFormattable

How does the following code implement multiple languages?

Double remain = 2000.5; var results= $"your money is {remain:C}"; Output your money is $2,000.50Copy the code

Use IFormattable for multiple languages

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.50Copy the code

The null operator (? .).

C# 6 added one? The. Operator returns null if an object or attribute is null, thus not executing the following code. NullException is often used in our code

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

Now, instead of writing IF, we can write it like this

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

This? The. Property can be used not only for values, but also for method calls. If the object is empty, nothing will be done.

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

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

It can also be used as an indexer for arrays

class Program { static void Main(string[] args) { User[] users = null; List<User> listUsers = null; // Console.WriteLine(users[1]? .Name); // Console.WriteLine(listUsers[1]? .Name); / / error Console. WriteLine (users? [1].Name); / / normal Console. WriteLine (listUsers? [1].Name); / / normal Console. ReadLine (); }}Copy the code

Note: while the above code saves a lot of code and reduces the number of empty exceptions, it should be used with caution, because sometimes we do need to throw empty exceptions, so using this feature can hide bugs

Third, the NameOf

In the past, we had a lot of places where we needed hard strings, which made refactoring difficult, and it was hard to detect a typo, for example

if (role == "admin")
{
}
Copy the code

WPF often has this code as well

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

Now that we have C#6 NameOf, we can do this

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();
    }
Copy the code

Note: NameOf only returns the string of Member. If there is an object or namespace before it, NameOf only returns. NameOf has many cases that are not supported, such as methods, keywords, object instances, and strings and expressions

4. Use Await in Catch and Finally

In previous versions, the C# team thought it was impossible to use Await in Catch and Finally, now they have implemented it in 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. }Copy the code

Expression method body

A one-sentence method body can be written as an arrow function without curly braces

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(); }}Copy the code

Automatic property initializer

Before, we had to assign the initialization value, which we usually do

public class Person { public int Age { get; set; } public Person() { Age = 100; }}Copy the code

But the new C# 6 feature does this

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

7. Read-only automatic properties

In C# 1 we can implement read-only properties like this

public class Person { private int age=100; public int Age { get { return age; }}}Copy the code

But when we have automatic properties, we can’t enforce read-only properties because automatic properties don’t support the readonly keyword, so we can only narrow down access

public class Person { public int Age { get; private set; }}Copy the code

But in C#6 we can implement readonly automatically

public class Person
{
    public int Age { get; } = 100;
}
Copy the code

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; }}Copy the code

Before, an exception can only be caught once, but now with Filter, the same exception can be filtered. As for what is useful, it depends on different people’s opinions. I think the above example, Defining two specific exceptions NameArgumentException and AgeArgumentException is easier to read.

Index initializer

This is mainly used in Dictionary, as for its use, I have not felt any use, who can know a good use scenario, welcome to add:

 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}");
        }
Copy the code

Static class methods can use static using

This one, in my opinion, is also a very useless one, but it’s also a way to get rid of prefixes and sometimes we don’t know where it’s coming from, and if you have a method with the same name and you don’t know which one to use, of course it turns out to use the override of the class itself, but it’s easy to get confused, isn’t it?

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

conclusion

I think the first to eight above are useful new features, I think the last few are not useful, of course, if you find a suitable use scenario should be useful, welcome to add.

Finally, have fun programming.