C# 9, Rekordy i duże zmian w .NET 5

Cezary Walenciuk

C# 9, Rekordy i duże zmian w .NET 5

@walenciukC

Speaker
  1. Co nowego w C# 9
  1. Co nowego w .NET 5
Jak utworzyć projekt w .NET 5
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk

Definicja projektu

                    
                        <Project Sdk="Microsoft.NET.Sdk">

                            <PropertyGroup>
                              <OutputType>Exe</OutputType>
                              <TargetFramework>netcoreapp3.1</TargetFramework>
                            </PropertyGroup>
                          
                        </Project>
                    
                

blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Swoją drogą .NET 5 to nie merge .NET FRAMEWORK i .NET Core. .NET 5 to bardziej następna iteracja .NET CORE 3.1 gdzie 4 została pominijęta.
Wiem, że wielu programistów nie może się doczekać na .NET MAUI, ale to dopiero w .NET 6 czyli za rok.
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Visual Studio 2019 v16.8 i co tam nowego
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
C# 9.0
C# 9.0 : Console Top Level Calls

C# 9.0 : Console Top Level Calls : 1

                    

                        using System;

                        namespace ConsoleTopLevelCallsNot
                        {
                            class Program
                            {
                                static void Main(string[] args)
                                {
                                    Console.WriteLine("Hello World!");
                                    Console.WriteLine(Substract(33, 11));

                                }

                                private static double Substract(double x, double y)
                                {
                                    return x - y;
                                }
                            }
                        }
                    
                

C# 9.0 : Console Top Level Calls : 2

                    
                        using System;
                        
                        Console.WriteLine("Hello World!");
                        Console.WriteLine(Substract2(33, 11));
                        
                        static double Substract2(double x, double y)
                        {
                            return x - y;
                        }
                    
                

blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk

C# 9.0 : Console Top Level Calls

C# 9.0 : Console Top Level Calls : 3

                    

                        using System;

                        namespace ConsoleTopLevelCallsNot
                        {
                            class Program
                            {
                                static void Main(string[] args)
                                {
                                    if (args.Length == 0)
                                    {
                                        System.Console.WriteLine("Please enter a numeric argument.");
                                    }
                                    

                                }
                            }
                        }
                    
                

C# 9.0 : Console Top Level Calls : 4

                    
                        using System;

                        if (args.Length == 0)
                        {
                            System.Console.WriteLine("Please enter a numeric argument.");
                        }
                    
                

blog
Copyright © Cezary Walenciuk
Initial Setters

Initial Setters : Przykład

                    
                        public class PirateModel
                        {
                            public int Id { get; set; }

                            public string CrewName { get; set; }
                    
                            public string Name { get; set; }
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Initial Setters : Przykład

                    
                        public static class InitialSetterExample
                        {
                            public static void Run()
                            {
                                PirateModel m = new PirateModel
                                { Name = "Luffy", CrewName = "StrawHats", Id = 1 };
                    
                                m.Id = 2;
                                m.Name = "Zorro";
                    
                                Console.WriteLine($"Hello {m.Name}, Id : {m.Id}");
                            }
                        }
                    
                

Co jeśli ja chce chronić te ID? Bo Entity Framework

Initial Setters : Przykład

                    
                        public class PirateModel
                        {
                            public int Id { get; private set; }
                    
                            public string CrewName { get; set; }
                    
                            public string Name { get; set; }
                        }
                    
                

Initial Setters : Przykład

                    
                        public class PirateModel
                        {
                            public int Id { get; private set; }
                    
                            public string CrewName { get; set; }
                    
                            public string Name { get; set; }
                    
                            public void UpdateId(int newId)
                            {
                                Id = newId;
                            }
                        }
                    
                

Initial Setters : Rozwiązanie

                    
                        public class PirateModel
                        {
                            public int Id { get; init; }
                    
                            public string CrewName { get; set; }
                    
                            public string Name { get; set; }
                        }
                    
                

blog
Copyright © Cezary Walenciuk
Krótsza wersja tworzenia klas

Krótsza wersja tworzenia klas

                    
                        PirateModel m3 = new();

                        PirateModel m4 = new()
                        { Name = "Zorro", CrewName = "StrawHats", Id = 2 };

                        //var m5 = new();
                    
                

Krótsza wersja tworzenia klas

                    
                        PirateModel m6;

                        //1000 linjek kodu później

                        m6 = new();
                    
                

Patter Matching w switch

Patter Matching w switch : przykład

                    
                        public class Weather
                        {
                            public DateTime Date { get; set; }
                    
                            public int TemperatureC { get; set; }
                    
                            public string Desc { get; set; }
                        }
                    
                

Patter Matching w switch : przykład

                    
                        public static List<Weather> CreateExample()
                        {
                            DateTime now = DateTime.Now;
                            var rng = new Random();
                
                            var exampleCollection = Enumerable.Range(1, 14).Select
                                (index => new Weather
                                {
                                    Date = now.AddDays(index),
                                    TemperatureC = rng.Next(-10, 40)
                                }
                            ).ToList();
                
                            return exampleCollection;
                        }
                    
                

Patter Matching w switch : przykład

                    

                        foreach (var weather in exampleList)
                        {
                            weather.Desc = weather.TemperatureC switch
                            {
                                <= 6 and > 1 => "Nie ciekawie. Ubrać sie trzeba",
                                10 or 9 or 8 or 7 => "Zimno",
                                11 => "Uwaga Łatwo zachorować",
                                12 => "Uwaga Kurtka",
                                13 => "Uwaga",
                                <= 15 => "Super",
                                <= 20 => "Ok",
                                <= 28 => "Gorąco",
                                >= 30 => "Upał",
                                _ => "Nie wiem"
                            };
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Patter Matching w switch : przykład

                    
                        public class Pizza
                        {
                            public string Name { get; set; }
                    
                            public bool HasMeat { get; set; }
                    
                            public bool HasAnanas { get; set; }
                    
                            public void Deconstruct(out string name, out bool hasMeat, out bool hasAnanas)
                            {
                                name = Name;
                                hasMeat = HasMeat;
                                hasAnanas = HasAnanas;
                            }
                        }
                    
                

Patter Matching w switch : przykład

                    
                        public class Pizza
                        {
                            public string Name { get; set; }
                    
                            public bool HasMeat { get; set; }
                    
                            public bool HasAnanas { get; set; }
                    
                            public void Deconstruct(out string name, out bool hasMeat, out bool hasAnanas)
                            {
                                name = Name;
                                hasMeat = HasMeat;
                                hasAnanas = HasAnanas;
                            }

                            public string Desc { get; set; }
                        }
                    
                

Patter Matching w switch : przykład

                    
                        public static List<Pizza> CreateExample()
                        {
                            var rng = new Random();
                
                            var exampleCollection = Enumerable.Range(1, 14).Select
                                (index => new Pizza
                                {
                                    Name = "P" + index.ToString() + rng.Next(1, 10).ToString(),
                                    HasMeat = rng.NextDouble() >= 0.5,
                                    HasAnanas = rng.NextDouble() >= 0.5
                                }
                            ).ToList();
                
                            return exampleCollection;
                        }
                    
                

Patter Matching w switch : przykład

                    
                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
            
                        var (name, hasananas, hasmeat) = a;
                        var (name2, hasananas2, hasmeat2) = b;
                    
                

Positional Pattern

Patter Matching w switch : Positional Pattern

                    
                        var exampleList = CreateExample();

                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
                        exampleList.Add(b); exampleList.Add(a);
            
                        foreach (var pizza in exampleList)
                        {
                            pizza.Desc = pizza switch
                            {
                                ("1", true, false) => "Taką zjem",
                                ("2", true, true) => "Ujdzie",
                                ("Peperoni", _, _) => "Moja ulubiona",
                                ("Marinara", _, _) => "Często jadam",
                                (_, _, true) => "Tej nie zjem",
                                _ => "Nie wiem"
                            };
                        }
                    
                

Patter Matching w switch : Positional Pattern

                    
                        var exampleList = CreateExample();

                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
                        exampleList.Add(b); exampleList.Add(a);
            
                        foreach (var pizza in exampleList)
                        {
                            pizza.Desc = pizza switch
                            {
                                ("2", _, var czymaAnans) => $"Pizza z Ananasem : {czymaAnans}",
                                { HasMeat : true} => "Ma mieso"
                            };
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Patter Matching w switch : Positional Pattern

                    
                        var exampleList = CreateExample();

                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
                        exampleList.Add(b); exampleList.Add(a);
            
                        foreach (var pizza in exampleList)
                        {
                            pizza.Desc = pizza switch
                            {
                                ("2", _, var czymaAnans) => $"Pizza z Ananasem : {czymaAnans}",
                            };
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Patter Matching w switch : Positional Pattern

                    
                        var exampleList = CreateExample();

                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
                        exampleList.Add(b); exampleList.Add(a);
            
                        foreach (var pizza in exampleList)
                        {
                            pizza.Desc = pizza switch
                            {
                                ("2", _, var czymaAnans) => $"Pizza z Ananasem : {czymaAnans}",
                                (HasMeat: true) => $"Ma mieso",
                                _ => throw new NotImlementedException()
                            };
                        }
                    
                

Tuple Pattern

Patter Matching w switch : Tuple Pattern

                    
                        var exampleList = CreateExample();

                        Pizza a = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Marinara" };
                        Pizza b = new Pizza() { HasAnanas = false, HasMeat = true, Name = "Peperoni" };
                        exampleList.Add(b); exampleList.Add(a);
            
                        foreach (var pizza in exampleList)
                        {
                            pizza.Desc = (pizza.HasMeat, pizza.HasAnanas) switch
                            {
                                (true, false) => "Super",
                                (false, true) => "Poprostu nie",
                                (false, false) => "Bez mięsa ?"
                            };
                        }
                    
                

Patterns w C# 9.0

Type pattern

Patter Matching w switch : Type pattern

                    
                        public class GreenTest : Test
                        {
                    
                        }
                    
                        public class RedTest : Test
                        {
                    
                        }
                    
                        public class Test
                        {
                    
                        }
                    
                

Patter Matching w switch : Type pattern

                    
                        public static List<Test> CreateExample()
                        {
                            var rng = new Random();
                            
                            List<Test> tests = new List<Test>();
                            
                            for (int i = 0; i < 15 ; i++)
                            {
                                if (rng.Next(1,100)  % 2 == 0)
                                    tests.Add(new GreenTest());
                                else
                                    tests.Add(new RedTest());
                            }
                            
                            return tests;
                        }
                    
                

Patter Matching w switch : Type pattern

                    
                        var exampleList = CreateExample();

                        foreach (var test in exampleList)
                        {
                            string outcome = test switch
                            {
                                GreenTest => "Postive",
                                RedTest => "Negative",
                                _ => "unknow"
                            };
                            Console.WriteLine(outcome);
                        }
                    
                

Relational pattern

Patter Matching w switch : Relational pattern

                    
                        public class GreenTest : Test
                        {
                    
                        }
                    
                        public class RedTest : Test
                        {
                    
                        }
                    
                        public class Test
                        {
                            public bool IsValid { get; set; }
                            public DateTimeOffset TestedOn { get; set; }
                    
                            public void Deconstruct(out int minutesSinceTest, out bool isValid)
                            {
                                minutesSinceTest = (int)(DateTimeOffset.UtcNow - TestedOn).TotalMinutes;
                                isValid = IsValid;
                            }
                        }
                    
                

Patter Matching w switch : Relational pattern

                    
                        var exampleList = CreateExample();

                        foreach (var test in exampleList)
                        {
                            string outcome = test switch
                            {
                                ( < 60 * 24 * 2, false) => "Nie poprawny test których jest młodszy niż 2 dni",
                                GreenTest(> 60 * 24, true) => "Postive, ale warto go po 24 godzinach zrobić ponownie",
                                _ => "unknow"
                            };
                            Console.WriteLine(outcome);
                        }
                    
                

Is Not

Is not

                    
                        PirateModel m1 = new PirateModel
                        { Name = "Luffy", CrewName = "StrawHats", Id = 1 };
            
                        PirateModel m2 = new()
                        { Name = "Zorro", CrewName = "StrawHats", Id = 2 };
            
                        PirateModel m3 = null;
            
                        if (m3 is null)
                        {
            
                        }
            
                        if (m2 is not null)
                        {
            
                        }
            
                        //if (m1 is not m2)
                        //{
            
                        //}
                    
                

blog
Copyright © Cezary Walenciuk
Jak użyć Rekordów z sensem

Czy Rekordy są typem wartościowym, czy typem referencyjnym?

                    
                        public record Record1(int  FirstNumber, int SecondNumber);

                        //Czy Rekordy są typem wartościowym, 
                        //Czy typem referencyjnym?
                    
                

Czy Rekordy są typem wartościowym, czy typem referencyjnym?

                    
                        Record1 rA = new(1, 2);
                        Record1 rAtest = rA;
                        Console.WriteLine(ReferenceEquals(rA, rAtest));

                        //true
                    
                

blog
Copyright © Cezary Walenciuk

Czy Rekordy są typem wartościowym, czy typem referencyjnym?

                    
                        //Czy rekord jako klasa wygląda tak

                        public class Record2
                        {
                            public string FirstNumber { get; set; }
                    
                            public string SecondNumber { get; set; }
                        }
                    
                

Czy Rekordy są typem wartościowym, czy typem referencyjnym?

                    
                        //Podobne do tej klasy, ale to jednak nie to samo
                        //o tym za chwilę

                        public class Record3
                        {
                            public string FirstNumber { get; init; }
                    
                            public string SecondNumber { get; init; }
                    
                            public Record3(string firstName, string lastName)
                            {
                                FirstName = firstName;
                                LastName = lastName;
                            }
                        }
                    
                

Czy Rekordy są typem wartościowym, czy typem referencyjnym?

                    
                        //To jest poprawny rekord

                        public record Record4
                        {
                            public int Number1 { get; set; }
                            public int Number2 { get; set; }
                        }
                    
                

Czy rekordy są immutable?

Czy rekordy są immutable?

                    
                        public record Record1(string FirstName, string LastName);

                        //Jest immutable czyli wartości w nim nie mogą być zmienione
                    
                

Czy rekordy są immutable?

                    
                        //Tutaj jest problem z nie jasnym działem rekordu

                        public record Record4
                        {
                            public int Number1 { get; set; }
                            public int Number2 { get; set; }
                        }
                    
                

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        //rekord to klasa tylko innaczej napisana
                        public record Record1(int FirstNumber, int SecondNumber);
                    
                

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        public class Class3
                        {
                            public int FirstNumber { get; init; }
                    
                            public int SecondNumber { get; init; }
                    
                            public Class3(int firstNumber, int secondNumber)
                            {
                                FirstNumber = firstNumber;
                                SecondNumber = secondNumber;
                            }
                        }
                    
                

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        Record1 rA = new(1, 2);
                        Record1 rB = new(1, 2);
                        Record1 rC = new(100, 200);
            
                        Class3 classA = new(1, 2);
                        Class3 classB = new(1, 2);
                        Class3 classC = new(100, 200);
                    
                

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        Console.WriteLine($"Record1 rA = new(1, 2);");
                        Console.WriteLine($"Record1 rB = new(1, 2);");
                        Console.WriteLine($"Check if they are Equal : {Equals(rA, rB)}");

                        Console.WriteLine("***");

                        Console.WriteLine($"Class3 classA = new(1, 2);");
                        Console.WriteLine($"Class3 classB = new(1, 2);");
                        Console.WriteLine($"Check if they are Equal : {Equals(classA, classB)}");
                    
                

blog
Copyright © Cezary Walenciuk

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        Console.WriteLine($"Record1 rA = new(1, 2);");
                        Console.WriteLine($"Record1 rB = new(1, 2);");
            
                        Console.WriteLine($"Check if they are Equal : {Equals(rA, rB)}");
            
                        Console.WriteLine($"Check if they are ReferenceEquals :" +
                            $"{ ReferenceEquals(rA, rB)}");
                    
                

blog
Copyright © Cezary Walenciuk

Rekordy, Klasy i metoda Equals, ReferenceEquals, ==, !=, GetHashCode()

                    
                        Console.WriteLine($"Record1 rA = new(1, 2);");
                        Console.WriteLine($"Record1 rB = new(1, 2);");

                        Console.WriteLine($"Check if they are Equal : {Equals(rA, rB)}");

                        Console.WriteLine($"Check if they are ReferenceEquals 
                        : {ReferenceEquals(rA, rB)}");

                        Console.WriteLine($"Check if they are == : {rA == rB}");
                    
                

blog
Copyright © Cezary Walenciuk

Jak to wygląda z rekordami

                    
                        Console.WriteLine($"Record1 rA = new(1, 2);");
                        Console.WriteLine($"Record1 rB = new(1, 2);");

                        Console.WriteLine($"Check if they are Equal : {Equals(rA, rB)}");

                        Console.WriteLine($"Check if they are ReferenceEquals : 
                        {ReferenceEquals(rA, rB)}");

                        Console.WriteLine($"Check if they are == : {rA == rB}");

                        Console.WriteLine($"Hash Code rA: {rA.GetHashCode()}");
                        Console.WriteLine($"Hash Code rB: {rB.GetHashCode()}");
                        Console.WriteLine($"Record1 rC = new(100, 200);");
                        Console.WriteLine($"Hash Code rC: {rC.GetHashCode()}");

                        Console.WriteLine($"Check if they are != : {rA != rC}");
                    
                

blog
Copyright © Cezary Walenciuk

Jak jest z klasami?

                    
                        Console.WriteLine($"Record3 classA = new(1, 2);");
                        Console.WriteLine($"Record3 classB = new(1, 2);");

                        Console.WriteLine($"Check if they are Equal : {Equals(classA, classB)}");
                        Console.WriteLine($"Check if they are ReferenceEquals : 
                        {ReferenceEquals(classA, classB)}");

                        Console.WriteLine($"Check if they are == : {classA == classB}");

                        Console.WriteLine($"Hash Code rA: {classA.GetHashCode()}");
                        Console.WriteLine($"Hash Code rB: {classB.GetHashCode()}");
                        Console.WriteLine($"Record3 classC = new(100, 200);");
                        Console.WriteLine($"Hash Code rC: {classC.GetHashCode()}");

                        Console.WriteLine($"Check if they are != : {classA != classC}");
                    
                

blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Deconstructor

Deconstructor

                    
                        Record1 rA = new(1, 2);

                        var (a, b) = rA;
                    
                

blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk

Deconstructor

                    
                        public class Record3
                        {
                            public int FirstNumber { get; init; }
                    
                            public int SecondNumber { get; init; }
                    
                            public Record3(int firstNumber, int secondNumber)
                            {
                                FirstNumber = firstNumber;
                                SecondNumber = secondNumber;
                            }
                    
                            public void Deconstruct(out int FirstNumber, out int SecondNumber)
                            {
                                FirstNumber = this.FirstNumber;
                                SecondNumber = this.SecondNumber;
                            }
                        }
                    
                

Użycie "with" aby utworzyć nowy rekord z istniejącego
blog
Copyright © Cezary Walenciuk

Klonownie shallow

                    
                        Record1 rA = new(1, 2);
                        Record1 rAtest = rA;
                        Console.WriteLine(ReferenceEquals(rA, rAtest));
            
                        Record1 newRa = rA with
                        {
                            SecondNumber = 200
                        };
                    
                

Czy można utworzyć rekordy generyczne?

Czy można utworzyć rekordy generyczne?

                    
                        public record Data<T>(int id, T Data);
                    
                

Czy rekordy mogą implementować interfejs

Czy rekordy mogą implementować interfejs

                    
                        public interface IProduct<T>
                        {
                           T Data { get; }
                        }

                        public record Game<T> : Audit ,IProduct<T>
                        {
                            public T Data { get; init; }
                        }
                    
                

blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Czy rekordy mogą być partial?

Czy rekordy mogą być partial?

                    
                        public partial record Data(string Name);
                    
                

Czy rekordy mogą użyć atrybutów?

Czy rekordy mogą użyć atrybutów?

                    
                        public record Data([property:JsonPropertyName("dataName")] string Name, 
                           [property:JsonPropertyName("dataCity")]string City);


                        public record Data([field:Foo("field")][property:Foo("prop")] string Name);

                    
                

Czy rekordy mogą użyć atrybutów?

                    
                        [AttributeUsage(AttributeTargets.All)]
                        class MyAttribute : Attribute
                        {
                           public MyAttribute(string _) { }
                        }
                         
                        public record Data([My("param")][field:My("field")][property:My("prop")] string Name);
                    
                

Czy rekordy mogą użyć atrybutów?

                    
                        public record Numbers
                        {
                            [JsonPropertyName("One")]
                            public string First { get; init; }
                    
                            [JsonPropertyName("Two")]
                            public string Second { get; init; }
                        }
                    
                

Dodanie metod i właściwości do rekordów

Dodanie metod i właściwości do rekordów

                    
                        //To jest tutaj problem z nie jasnym działem rekordu

                        public record Record4
                        {
                            public int Number1 { get; set; }
                            public int Number2 { get; set; }
                        }
                    
                

Dodanie metod i właściwości do rekordów

                    
                        public record Record5(int FirstNumber, int SecondNumber);

                        public record Record6(int FirstNumber, int SecondNumber)
                        {
                            internal int SecondNumber { get; init; } = SecondNumber;
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Dodanie metod i właściwości do rekordów

                    
                        public record Record7(int FirstNumber, int SecondNumber)
                        {
                            internal int SecondNumber { get; init; } = SecondNumber;
                    
                            public string JavaScriptLikeSumOfNumbers { get => $"{FirstNumber}{SecondNumber}"}
                        }
                    
                

Dodanie metod i właściwości do rekordów

                    
                        public record Record8(int FirstNumber, int SecondNumber)
                        {
                            public (int,int) ReturnHasCodes()
                            {
                                return (FirstNumber.GetHashCode(), SecondNumber.GetHashCode());
                            }
                        }
                    
                

blog
Copyright © Cezary Walenciuk
Dziedziczenie rekordów
blog
Copyright © Cezary Walenciuk
Zalety

Zalety Rekordów

Kiedy ich użyć?

Kiedy ich użyć?

Kiedy ich nie użyć?

Kiedy ich nie użyć?

Inne zmiany : Natywne Int

                    
                        nint nativeInt = 55;

                        Console.WriteLine(nint.MaxValue);

                        Compiled in x86 Configuration
                        Output: 2147483647
                        Compiled in x64 Configuration
                        Output: 9223372036854775807
                    
                

Inne zmiany : Discard w Lambda

                    
                        Func<int,int,int> zero = (_,_) => 0;
                    
                

Inne zmiany : partial w metodzie

                    
                        partial class Doing
                        {
                            internal partial bool DoSomething(string s, out int i);
                        }

                        partial class Doing
                        {
                            internal partial bool DoSomething(string s, out int i)
                            {
                                i = 0;
                                return true;
                            }
                        }
                    
                

Inne zmiany : Konwariancyjne typy zwracane

                    
                        public virtual Cat GetCat()
                        {
                            // This is the parent (or base) class.
                            return new Cat();
                        }

                        public override Cat GetCat
                        {
                            //You can return the child class, but still return a Cat
                            return new Tigger();
                        }
                    
                

Inne zmiany : Konwariancyjne typy zwracane

                    
                        public virtual Cat GetCat()
                        {
                            // This is the parent (or base) class.
                            return new Cat();
                        }

                        public override Tiger GetCat()
                        {
                            return new Tigger();
                        }
                    
                

blog
Copyright © Cezary Walenciuk

Inne zmiany : GetEnumerator jako extension method

                    
                        public static class Extensions
                        {
                            public static IEnumerator<T> GetEnumerator<T> (this IEnumerator<T> enumerator) =>
                        }
                    
                

.NET 5
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Pytanie czy słowo "Core" zniknie z ASP.NET Core
Oficjalna nazwa to ASP.NET Core for .NET 5
Pytanie : Co z przyszłością .NET Standardu
blog
Copyright © Cezary Walenciuk
Pytanie : Jaka jest róźnica pomiędzy ASP.NET Core 3.2 a ASP.NET Core for .NET 5
blog
Copyright © Cezary Walenciuk
Co to oznacza dla nas ?
Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Czego nie lubię w C# i w .NET ?

Co ludzie chcą od C# ?

Bonus
WPF
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Visual Studio Apply XAML Hot Reload on Document save
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Publikowanie aplikacji WPF i Windows Forms w .NET 5
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
blog
Copyright © Cezary Walenciuk
Dzięki za obecność