Что нам готовит грядущий c#7?

41
Что нам готовит грядущий C#7? Андрей Акиньшин, JetBrains Community Dev Camp 2015 1/27

Upload: andrey-akinshin

Post on 11-Feb-2017

242 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Что нам готовит грядущий C#7?

Что нам готовит грядущий C#7?

Андрей Акиньшин, JetBrains

Community Dev Camp 2015

1/27

Page 2: Что нам готовит грядущий C#7?

C#7

2/27

Page 3: Что нам готовит грядущий C#7?

Tuples (Background)

public void Tally(IEnumerable<int> values, out int sum, out int count)

int s, c;Tally(myValues, out s, out c);Console.WriteLine($"Sum: {s}, count: {c}");

public Tuple<int, int> Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Item1}, count: {t.Item2}")

public struct TallyResult { public int Sum; public int Count; }public TallyResult Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Sum}, count: {t.Count}");

3/27

Page 4: Что нам готовит грядущий C#7?

Tuples (Background)

public void Tally(IEnumerable<int> values, out int sum, out int count)

int s, c;Tally(myValues, out s, out c);Console.WriteLine($"Sum: {s}, count: {c}");

public Tuple<int, int> Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Item1}, count: {t.Item2}")

public struct TallyResult { public int Sum; public int Count; }public TallyResult Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Sum}, count: {t.Count}");

3/27

Page 5: Что нам готовит грядущий C#7?

Tuples (Background)

public void Tally(IEnumerable<int> values, out int sum, out int count)

int s, c;Tally(myValues, out s, out c);Console.WriteLine($"Sum: {s}, count: {c}");

public Tuple<int, int> Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Item1}, count: {t.Item2}")

public struct TallyResult { public int Sum; public int Count; }public TallyResult Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Sum}, count: {t.Count}");

3/27

Page 6: Что нам готовит грядущий C#7?

Tuples (Background)

public void Tally(IEnumerable<int> values, out int sum, out int count)

int s, c;Tally(myValues, out s, out c);Console.WriteLine($"Sum: {s}, count: {c}");

public Tuple<int, int> Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Item1}, count: {t.Item2}")

public struct TallyResult { public int Sum; public int Count; }public TallyResult Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.Sum}, count: {t.Count}");

3/27

Page 7: Что нам готовит грядущий C#7?

Tuples types

public (int sum, int count) Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.sum}, count: {t.count}");

public async Task<(int sum, int count)>TallyAsync(IEnumerable<int> values)

var t = await TallyAsync(myValues);Console.WriteLine($"Sum: {t.sum}, count: {t.count}");

4/27

Page 8: Что нам готовит грядущий C#7?

Tuples types

public (int sum, int count) Tally(IEnumerable<int> values)

var t = Tally(myValues);Console.WriteLine($"Sum: {t.sum}, count: {t.count}");

public async Task<(int sum, int count)>TallyAsync(IEnumerable<int> values)

var t = await TallyAsync(myValues);Console.WriteLine($"Sum: {t.sum}, count: {t.count}");

4/27

Page 9: Что нам готовит грядущий C#7?

Tuple literals and deconstruction

var t = new (int sum, int count) { sum = 0, count = 0 };

public (int sum, int count) Tally(IEnumerable<int> values){

var s = 0; var c = 0;foreach (var value in values) { s += value; c++; }

return (s, c); // target typed to (int sum, int count)}

public (int sum, int count) Tally(IEnumerable<int> values){

// infer tuple type from names and valuesvar res = (sum: 0, count: 0);foreach (var value in values) { res.sum += value; res.count++; }

return res;}

(var sum, var count) = Tally(myValues); // deconstruct resultConsole.WriteLine($"Sum: {sum}, count: {count}");

5/27

Page 10: Что нам готовит грядущий C#7?

Tuple literals and deconstruction

var t = new (int sum, int count) { sum = 0, count = 0 };

public (int sum, int count) Tally(IEnumerable<int> values){

var s = 0; var c = 0;foreach (var value in values) { s += value; c++; }

return (s, c); // target typed to (int sum, int count)}

public (int sum, int count) Tally(IEnumerable<int> values){

// infer tuple type from names and valuesvar res = (sum: 0, count: 0);foreach (var value in values) { res.sum += value; res.count++; }

return res;}

(var sum, var count) = Tally(myValues); // deconstruct resultConsole.WriteLine($"Sum: {sum}, count: {count}");

5/27

Page 11: Что нам готовит грядущий C#7?

Tuple literals and deconstruction

var t = new (int sum, int count) { sum = 0, count = 0 };

public (int sum, int count) Tally(IEnumerable<int> values){

var s = 0; var c = 0;foreach (var value in values) { s += value; c++; }

return (s, c); // target typed to (int sum, int count)}

public (int sum, int count) Tally(IEnumerable<int> values){

// infer tuple type from names and valuesvar res = (sum: 0, count: 0);foreach (var value in values) { res.sum += value; res.count++; }

return res;}

(var sum, var count) = Tally(myValues); // deconstruct resultConsole.WriteLine($"Sum: {sum}, count: {count}");

5/27

Page 12: Что нам готовит грядущий C#7?

Tuple literals and deconstruction

var t = new (int sum, int count) { sum = 0, count = 0 };

public (int sum, int count) Tally(IEnumerable<int> values){

var s = 0; var c = 0;foreach (var value in values) { s += value; c++; }

return (s, c); // target typed to (int sum, int count)}

public (int sum, int count) Tally(IEnumerable<int> values){

// infer tuple type from names and valuesvar res = (sum: 0, count: 0);foreach (var value in values) { res.sum += value; res.count++; }

return res;}

(var sum, var count) = Tally(myValues); // deconstruct resultConsole.WriteLine($"Sum: {sum}, count: {count}");

5/27

Page 13: Что нам готовит грядущий C#7?

Tuples: проблемы

• Struct or class• Mutability• Tuples as fields• Conversions• . . .

Cм. также: roslyn#347

6/27

Page 14: Что нам готовит грядущий C#7?

Pattern matching (Background)// class Person(string Name);class Person{

public Person(string name) { this.Name = name; }public string Name { get; }

}

// class Student(string Name, double Gpa) : Person(Name);class Student : Person{

public Student(string name, double gpa) : base(name){ this.Gpa = gpa; }

public double Gpa { get; }}

// class Teacher(string Name, string Subject) : Person(Name);class Teacher : Person{

public Teacher(string name, string subject) : base(name){ this.Subject = subject; }

public string Subject { get; }}

7/27

Page 15: Что нам готовит грядущий C#7?

Pattern matching (Background)static string PrintedForm(Person p){

Student s;Teacher t;if ((s = p as Student) != null && s.Gpa > 3.5){

return $"Honor Student {s.Name} ({s.Gpa})";}else if (s != null){

return $"Student {s.Name} ({s.Gpa})";}else if ((t = p as Teacher) != null){

return $"Teacher {t.Name} of {t.Subject}";}else{

return $"Person {p.Name}";}

}

8/27

Page 16: Что нам готовит грядущий C#7?

Pattern matching (Background)

static void Main(string[] args){

Person[] oa = {new Student("Einstein", 4.0),new Student("Elvis", 3.0),new Student("Poindexter", 3.2),new Teacher("Feynmann", "Physics"),new Person("Anders"),

};foreach (var o in oa){

Console.WriteLine(PrintedForm(o));}Console.ReadKey();

}

9/27

Page 17: Что нам готовит грядущий C#7?

Pattern matching: is

static string PrintedForm(Person p){

if (p is Student s && s.Gpa > 3.5){

return $"Honor Student {s.Name} ({s.Gpa})";}else if (p is Student s){

return $"Student {s.Name} ({s.Gpa})";}else if (p is Teacher t){

return $"Teacher {t.Name} of {t.Subject}";}else{

return $"Person {p.Name}";}

}

10/27

Page 18: Что нам готовит грядущий C#7?

Pattern matching: switch

static string PrintedForm(Person p){

switch (p){

case Student s when s.Gpa > 3.5 :return $"Honor Student {s.Name} ({s.Gpa})";

case Student s :return $"Student {s.Name} ({s.Gpa})";

case Teacher t :return $"Teacher {t.Name} of {t.Subject}";

default :return $"Person {p.Name}";

}}

11/27

Page 19: Что нам готовит грядущий C#7?

Pattern matching: match

static string PrintedForm(Person p){

return p match (case Student s when s.Gpa > 3.5 :

$"Honor Student {s.Name} ({s.Gpa})"case Student s :

$"Student {s.Name} ({s.Gpa})"case Teacher t :

$"Teacher {t.Name} of {t.Subject}"case * :

$"Person {p.Name}");

}

12/27

Page 20: Что нам готовит грядущий C#7?

Pattern matching: Exceptions

return p match (case Student s when s.Gpa > 3.5 :

$"Honor Student {s.Name} ({s.Gpa})"case Student s :

$"Student {s.Name} ({s.Gpa})"case Teacher t :

$"Teacher {t.Name} of {t.Subject}"case null :

throw new ArgumentNullException(nameof(p))case * :

$"Person {p.Name}");

13/27

Page 21: Что нам готовит грядущий C#7?

Pattern matching: members

return p match (case Student s when s.Gpa > 3.5 :

$"Honor Student {s.Name} ({s.Gpa})"case Student { Name is "Poindexter" } :

"A Nerd"case Student s :

$"Student {s.Name} ({s.Gpa})"case Teacher t :

$"Teacher {t.Name} of {t.Subject}"case null :

throw new ArgumentNullException(nameof(p))case * :

$"Person {p.Name}");

14/27

Page 22: Что нам готовит грядущий C#7?

Pattern matching: =>

static string PrintedForm(Person p) => p match (case Student s when s.Gpa > 3.5 :

$"Honor Student {s.Name} ({s.Gpa})"case Student { Name is "Poindexter" } :

"A Nerd"case Student s :

$"Student {s.Name} ({s.Gpa})"case Teacher t :

$"Teacher {t.Name} of {t.Subject}"case null :

throw new ArgumentNullException(nameof(p))case * :

$"Person {p.Name}");

15/27

Page 23: Что нам готовит грядущий C#7?

Readonly locals

readonly int foo = /* ... */ ;readonly var foo = /* ... */ ;val foo = /* ... */ ;public void Bar(readonly int foo = 0)public void Bar(readonly ref Matrix3D matrix)

16/27

Page 24: Что нам готовит грядущий C#7?

Immutable Typespublic immutable struct Tuple<T1, T2>{

public Tuple(T1 item1, T2 item2){ Item1 = item1; Item2 = item2; }

public T1 Item1; // Implicitly readonlypublic T2 Item2; // Implicitly readonly

}

public immutable struct ImmutableTuple<T1, T2>(T1 item1, T2 item2)

where T1 : immutablewhere T2 : immutable

{public ImmutableTuple(T1 item1, T2 item2)

{ Item1 = item1; Item2 = item2; }public T1 Item1;public T2 Item2;

}

17/27

Page 25: Что нам готовит грядущий C#7?

Immutable Typespublic immutable struct Tuple<T1, T2>{

public Tuple(T1 item1, T2 item2){ Item1 = item1; Item2 = item2; }

public T1 Item1; // Implicitly readonlypublic T2 Item2; // Implicitly readonly

}

public immutable struct ImmutableTuple<T1, T2>(T1 item1, T2 item2)

where T1 : immutablewhere T2 : immutable

{public ImmutableTuple(T1 item1, T2 item2)

{ Item1 = item1; Item2 = item2; }public T1 Item1;public T2 Item2;

}

17/27

Page 26: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен3 Процесс компиляции не меняется4 Runtime ничего не знает про not-nullable5 Обратная совместимость

18/27

Page 27: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен3 Процесс компиляции не меняется4 Runtime ничего не знает про not-nullable5 Обратная совместимость

18/27

Page 28: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен

3 Процесс компиляции не меняется4 Runtime ничего не знает про not-nullable5 Обратная совместимость

18/27

Page 29: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен3 Процесс компиляции не меняется

4 Runtime ничего не знает про not-nullable5 Обратная совместимость

18/27

Page 30: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен3 Процесс компиляции не меняется4 Runtime ничего не знает про not-nullable

5 Обратная совместимость

18/27

Page 31: Что нам готовит грядущий C#7?

Nullability?!

1 Добавляем в язык только ? и ! приобъявления и кастах

2 NullReferenceException невозможен3 Процесс компиляции не меняется4 Runtime ничего не знает про not-nullable5 Обратная совместимость

18/27

Page 32: Что нам готовит грядущий C#7?

Local functions

static void Main(string[] args){

int Fib(int n) => (n < 2)? 1: Fib(n - 1) + Fib(n - 2);

Console.WriteLine(Fib(7));}

19/27

Page 33: Что нам готовит грядущий C#7?

Extensions properties

public static class MyClassExtensions{

public static int Data[this MyClass obj]{

get { return 0; }set { return; }

}}var data = myObj.Data;myObj.Data = 1;

20/27

Page 34: Что нам готовит грядущий C#7?

Binary literals and Digits separators

int bin = 0b1001_1010_0001_0100;int hex = 0x1b_a0_44_fe;int dec = 33_554_432;int weird = 1_2__3___4____5_____6______7_______8________9;double real = 1_000.111_1e-1_000;

21/27

Page 35: Что нам готовит грядущий C#7?

params IEnumerable

WriteLine(params object[] args)WriteLine(params IEnumerable<object> args)

22/27

Page 36: Что нам готовит грядущий C#7?

Method contracts

public int Insert(T item, int index){

Contract.Requires(index >= 0 && index <= Count);Contract.Ensures(Contract.Result<int>() >= 0 &&

Contract.Result<int>() < Count);return InsertCore(item, index);

}

public int Insert(T item, int index)requires index >= 0 && index <= Countensures return >= 0 && return < Count

{return InsertCore(item, index);

}

23/27

Page 37: Что нам готовит грядущий C#7?

Method contracts

public int Insert(T item, int index){

Contract.Requires(index >= 0 && index <= Count);Contract.Ensures(Contract.Result<int>() >= 0 &&

Contract.Result<int>() < Count);return InsertCore(item, index);

}

public int Insert(T item, int index)requires index >= 0 && index <= Countensures return >= 0 && return < Count

{return InsertCore(item, index);

}

23/27

Page 38: Что нам готовит грядущий C#7?

corefxlab: System.Slices

public partial struct Span<T> : IEnumerable<T>, IEquatable<Span<T>>{

readonly object _object;readonly UIntPtr _offset;public readonly int Length;// ...Span(T[] array, int start, int length)unsafe Span(void* ptr, int length)bool TryCopyTo(Span<T> dest)Span<T> Slice(int start, int length)

}

// Extensionsstatic Span<T> Slice<T>(this T[] array, int start, int length)static Span<char> Slice(this string str, int start, int length)static Span<U> Cast<[Primitive]T, [Primitive]U>(this Span<T> slice)static bool SequenceEqual<T>(this Span<T> first, Span<T> second)// ...

24/27

Page 39: Что нам готовит грядущий C#7?

Array slicing syntax

int[] primes = new int[] { 2, 3, 5, 7, 9, 11, 13 };int item = primes[1]; // Regular array access (value 3)int[:] a = primes[0:3]; // A slice {2, 3, 5}int[:] b = primes[1:2]; // A slice {3}int[:] c = primes[:5]; // A slice {2, 3, 5, 7, 9}int[:] d = primes[2:]; // A slice {5, 7, 9, 11, 13}int[:] e = primes[:]; // A slice {2, 3, 5, 7, 9, 11, 13}int[:] f = a[1:2]; // A slice {3}int[:] g = primes[:]; // A slice {2, 3, 5, 7, 9, 11, 13}int[:] h = primes; // A slice {2, 3, 5, 7, 9, 11, 13}int[:] i = h[:]; // A slice {2, 3, 5, 7, 9, 11, 13}

25/27

Page 40: Что нам готовит грядущий C#7?

github

26/27

Page 41: Что нам готовит грядущий C#7?

Вопросы?

Андрей Акиньшин, JetBrainshttp://aakinshin.net

https://github.com/AndreyAkinshinhttps://twitter.com/andrey_akinshin

[email protected]

27/27