Tuga IT 2017 - Whats new in C# 7

  • Published on
    18-Mar-2018

  • View
    259

  • Download
    9

Transcript

TUGA IT 2017LISBON, PORTUGALTHANK YOU TO OUR SPONSORSPLATINUMGOLD SILVERPARTICIPATING COMMUNITIESCLOUD PRO PTPaulo Morgado PauloMorgado.NET @PauloMorgado github.com/paulomorgado stackoverflow.com/users/402366/paulo-morgado slideshare.net/PauloJorgeMorgado docs.com/paulo-morgado/ revista-programar.info/author/pmorgado/ fca.pt/pt/catalogo-pesquisa/?filtros=2&pesquisa=Paulo+Morgadohttps://mvp.microsoft.com/en-us/PublicProfile/8656https://mvp.microsoft.com/en-us/PublicProfile/8656http://paulomorgado.net/https://twitter.com/PauloMorgadohttps://github.com/paulomorgadohttps://stackoverflow.com/users/402366/paulo-morgadohttps://www.slideshare.net/PauloJorgeMorgadohttps://docs.com/paulo-morgado/http://www.revista-programar.info/author/pmorgado/https://www.fca.pt/pt/catalogo-pesquisa/?filtros=2&pesquisa=Paulo+Morgadohttp://www.vision-box.com/http://www.vision-box.com/Agenda Literal improvements More expression bodied members Throw expressions Out variables Pattern matching Tuples Local functions Ref returns and locals Generalized async return typesLiteral improvementsvar n = 123456789;var n = 0x075BCD15;Binary Literalsvar n = 0b00000111010110111100110100010101;Digit Separatorsvar d = 123_456_789;var x = 0x075B_CD15;var b = 0b0000_0111_0101_1011_1100_1101_0001_0101;0b_0000_0111_0101_1011_1100_1101_0001_0101_;0b0000__0111__0101__1011__1100__1101__0001__0101; More expression bodied membersclass Person{private static ConcurrentDictionary names= new ConcurrentDictionary();private int id = GetId();public Person(string name) => names.TryAdd(id, name); // constructors~Person() => names.TryRemove(id, out _); // destructorspublic string Name{get => names[id]; // gettersset => names[id] = value; // setters}}Throw expressionsclass Person{public string Name { get; }public Person(string name)=> Name = name ?? throw new ArgumentNullException(nameof(name));public string GetFirstName(){var parts = Name.Split(" ");return (parts.Length > 0)? parts[0]: throw new InvalidOperationException("No name!");}public string GetLastName() => throw new NotImplementedException();}Out variablespublic void PrintCoordinates(Point p){int x, y;p.GetCoordinates(out x, out y);WriteLine($"({x}, {y})");}public void PrintCoordinates(Point p){p.GetCoordinates(out int x, out int y);WriteLine($"({x}, {y})");}public void PrintCoordinates(Point p){p.GetCoordinates(out var x, out var y);WriteLine($"({x}, {y})");}Out variables - disacardspublic void PrintCoordinates(Point p){p.GetCoordinates(out var x, out _);WriteLine($"{x}");}Pattern matchingpublic void PrintStars(object o){if (o is null) return; // constant pattern "null"if (!(o is int i)) return; // type pattern "int i"WriteLine(new string('*', i));}if (o is int i || (o is string s && int.TryParse(s, out i))){/* use i */}Pattern matchingswitch (shape){case Ellipse e:WriteLine($"It's a {e.Height} x {e.Width} ellipse.");break;case Rectangle r:WriteLine($"{r.Height} x {r.Width} rectangle");break;default:WriteLine("");break;case null:throw new ArgumentNullException(nameof(shape));} switch (shape){case Ellipse c when c.Height == c.Width:WriteLine($"It's a {c.Height} circle.");break;case Ellipse e:WriteLine($"It's a {e.Height} x {e.Width} ellipse.");break;case Rectangle s when (s.Height == s.Width):WriteLine($"It's a {s.Height} square");break;case Rectangle r:WriteLine($"It's a {r.Height} x {r.Width} rectangle");break;default:WriteLine("");break;case null:throw new ArgumentNullException(nameof(shape));} TuplesTuple LookupName(long id) // tuple return type{// retrieve first, middle and last from data storagereturn Tuple.Create(first, middle, last); // tuple value}var names = LookupName(id);WriteLine($"found {names.Item1} {names.Item3}.");(string, string, string) LookupName(long id) // tuple return type{// retrieve first, middle and last from data storagereturn (first, middle, last); // tuple literal}var names = LookupName(id);WriteLine($"found {names.Item1} {names.Item3}.");(string first, string middle, string last) LookupName(long id) // tuple return type{// retrieve first, middle and last from data storagereturn (first, middle, last); // tuple literal}var names = LookupName(id);WriteLine($"found {names.first} {names.last}.");Tuples// named tuple elements in a literal;var names = (first: first, middle: middle, last: last);WriteLine($"found {names.first} {names.last}.");Tuples - deconstruction(string first, string middle, string last) LookupName(long id)// deconstructing declaration(string first, string middle, string last) = LookupName(id);WriteLine($"found {first} {last}.");(string first, string middle, string last) LookupName(long id)// var inside(var first, var middle, var last) = LookupName(id);WriteLine($"found {first} {last}.");(string first, string middle, string last) LookupName(long id)// var outsidevar (first, middle, last) = LookupName(id);WriteLine($"found {first} {last}.");Tuple - deconstructionclass Point{public int X { get; }public int Y { get; }public Point(int x, int y) { X = x; Y = y; }public void Deconstruct(out int x, out int y) { x = X; y = Y; }}(var myX, var myY) = GetPoint();(var myX, _) = GetPoint(); // I only care about myX// calls Deconstruct(out myX, out myY);Tuples Tuples are value types, and their elements are simply public, mutable fields. They have value equality, meaning that two tuples are equal (and have the same hash code) if all their elements are pairwise equal (and have the same hash code). This makes tuples useful for many other situations beyond multiple return values. For instance, if you need a dictionary with multiple keys, use a tuple as your key and everything works out right. If you need a list with multiple values at each position, use a tuple, and searching the list etc. will work correctly. Tuples rely on a family of underlying generic struct types called ValueTuple. If you target a Framework that doesnt yet include those types, you can instead pick them up from NuGet: Right-click the project in the Solution Explorer and select "Manage NuGet Packages" Select the "Browse" tab and select "nuget.org" as the "Package source" Search for "System.ValueTuple" and install it.public int Fibonacci(int x){if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));return Fib(x).current;}private (int current, int previous) Fib(int i){if (i == 0) return (1, 0);var (p, pp) = Fib(i - 1);return (p + pp, p);}Local functionspublic int Fibonacci(int x){if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));return Fib(x).current;(int current, int previous) Fib(int i){if (i == 0) return (1, 0);var (p, pp) = Fib(i - 1);return (p + pp, p);}}Local functionsprivate string Tweetify(string msg){if (msg.Length >= TweetSize) return msg.Substring(0, TweetSize - 3) + "...";var sb = new StringBuilder(msg);var random = new Random();while (TryAddHashTag()) { }return sb.ToString();bool TryAddHashTag(){var r = random.Next(0, Hashtags.Length);var hashtag = " " + Hashtags[r];if (sb.Length + hashtag.Length > TweetSize) return false;sb.Append(hashtag);return true;}} Local functionspublic IEnumerable Filter(IEnumerable source, Func filter){if (source == null) throw new ArgumentNullException(nameof(source));if (filter == null) throw new ArgumentNullException(nameof(filter));return Iterator();IEnumerable Iterator(){foreach (var element in source){if (filter(element)) { yield return element; }}}}Local functionspublic async Task Index(int i){return await GetStuffAsync();async Task GetStuffAsync(){var someStuff = await GetSomeStuffAsync(i).ConfigureAwait(false);var moreStuff = await GetMoreStuffAsync(i).ConfigureAwait(false);/// ...return result;}}Ref returns and localspublic ref int Find(int number, int[] numbers){for (int i = 0; i < numbers.Length; i++){if (numbers[i] == number){return ref numbers[i]; // return the storage location, not the value}}throw new IndexOutOfRangeException($"{nameof(number)} not found");}int[] array = { 1, 15, -39, 0, 7, 14, -12 };ref int place = ref Find(7, array); // aliases 7's place in the arrayplace = 9; // replaces 7 with 9 in the arrayWriteLine(array[4]); // prints 9Generalized async return typespublic async Task GetValueAsync(){return await GetValueMyAsync();}private abstract MyTask GetValueMyAsync(); public class MyTask{public MyAwaitable GetAwaiter();}public class MyAwaitable : INotifyCompletion{public bool IsCompleted { get; }public T GetResult();public void OnCompleted(Action continuation);}public class MyAwaitable : INotifyCompletion, ICriticalNotifyCompletion{public bool IsCompleted { get; }public T GetResult();public void OnCompleted(Action continuation);public void UnsafeOnCompleted(Action continuation);}Generalized async return types[AsyncMethodBuilder(typeof(MyAsyncMethodBuilder))]public class MyTask{public MyAwaitable GetAwaiter();}public class MyAsyncMethodBuilder{public static MyAsyncMethodBuilder Create();public void Start(ref TStateMachine stateMachine)where TStateMachine : IAsyncStateMachine;public void SetStateMachine(IAsyncStateMachine stateMachine);public void SetException(Exception exception);public void SetResult(T result);public void AwaitOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine)where TAwaiter : INotifyCompletionwhere TStateMachine : IAsyncStateMachine;public void AwaitUnsafeOnCompleted(ref TAwaiter awaiter, ref TStateMachine stateMachine)where TAwaiter : ICriticalNotifyCompletionwhere TStateMachine : IAsyncStateMachine;public MyTask Task { get; }} Generalized async return typesUp until now, async methods in C# must either return void, Task or Task. C# 7.0 allows other types to be defined in such a way that they can be returned from an async method.For instance we now have a ValueTask struct type. It is built to prevent the allocation of a Task object in cases where the result of the async operation is already available at the time of awaiting. For many async scenarios where buffering is involved for example, this can drastically reduce the number of allocations and lead to significant performance gains.There are many other ways that you can imagine custom "task-like" types being useful. It wont be straightforward to create them correctly, so we dont expect most people to roll their own, but it is likely that they will start to show up in frameworks and APIs, and callers can then just return and await them the way they do Tasks today.Resources What's new in C# 7 https://docs.microsoft.com/dotnet/articles/csharp/whats-new/csharp-7 New Features in C# 7.0 https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/ C# Language Design https://github.com/dotnet/csharplang/ .NET Compiler Platform ("Roslyn") https://github.com/dotnet/roslyn Visual Studio 2017 https://www.visualstudio.com/vs/whatsnew/ LINQPad http://www.linqpad.net/https://docs.microsoft.com/dotnet/articles/csharp/whats-new/csharp-7https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/?Wt.mc_id=DX_MVP8656https://github.com/dotnet/csharplang/https://github.com/dotnet/roslynhttps://www.visualstudio.com/vs/whatsnew/http://www.linqpad.net/PLEASE FILL IN EVALUATION FORMSFRIDAY, MAY 19th SATURDAY, MAY 20thhttps://survs.com/survey/cprwce7pi8 https://survs.com/survey/l9kksmlzd8YOUR OPINION IS IMPORTANT!https://survs.com/survey/cprwce7pi8https://survs.com/survey/l9kksmlzd8THANK YOU TO OUR SPONSORSPLATINUMGOLD SILVER