Thursday, December 14, 2017

C# 7.0 & 7.1 , 7.2

1. Discards (C# 7.0)

a. Use with Out Param

private void DiiscardTest()
        {
            //Before  C# 7.0

            string s = "4";
            if (int.TryParse(s,out int x))
            {
                Console.WriteLine("This is an intger");
            }
            int y;            
            if (int.TryParse(s, out y))
            {
                Console.WriteLine("This is an integer");
            }

            //After C# 7.0
            if (int.TryParse(s, out int _))
            {
                Console.WriteLine("This is an intger");
            }

            if (int.TryParse(s, out _))
            {
                Console.WriteLine("This is an intger");
            }
//It is applicable on multiparameter

        }

b. Discard With Tuple

private void DiscardWithTuple()
        {
            Program p = new Program();

            //Before C# 7.0
            (int id, String name) = p.GetDetail();

            //After C$ 7.0
            (int ID, _) = p.GetDetail();

        }

        private (int id, String name) GetDetail() => (1, "red");

c. Use Discard alone

 private void DiscardAlone()
        {
            //Before C# 7.0
            int x = 90;
            bool y = x > 90 ? UpdateID() : UpdateName();

            //After C# 7.0
            _ = x > 90 ? UpdateID() : UpdateName();
        }

        private bool UpdateID()
        {
            //Updated...
            //............
            return true;
        }

        private bool UpdateName()
        {
            //Updated...
            //............
            return true;
        }

d. Use Discard in Pattern Matching

private void DoWork(dynamic c)
        {
            if (c is int)
            {
                Console.WriteLine("c is an intger");
            }
            else if (c is string)
            {
                Console.WriteLine("c is a String");
            }
            else if(c is var _)
            {
                Console.WriteLine("Unknow Type");
            }
        }

e. Discard with Tasks

Before C# 7.0

static void Main(string[] args) => PrintOddNumbers(20);  
  
private static void PrintOddNumbers(int maxNumber)  
{  
  Task task = Run(() => {   
    for (int i = 1; i < maxNumber; i += 2)  
    {  
        Write($"{i}\t");  
        Sleep(500);  
    }  
    });              
   Delay(300*maxNumber).Wait();  

In above example there is no use of task, so using discard we can avoid task

After C# 7.0

private static void PrintOddNumbers(int maxNumber)  
{  
  _= Run(() => {   
    for (int i = 1; i < maxNumber; i += 2)  
    {  
        Write($"{i}\t");  
        Sleep(500);  
    }  
    });              
   Delay(300*maxNumber).Wait();  

2. 'is' type Pattern Matching


Before C# 7.0 
        private static void PrintObject(dynamic x)
        {
            if (x is Seller)
            {
                var c = x as Seller;
                WriteLine($"Seller Id : {c.Id} Seller Name {c.Name}");
            }
            if (x is Manager)
            {
                var p = x as Manager;
                WriteLine($"Manager Id : {p.ManagertId} Manager Name {p.Name}");
            }
            else
                WriteLine("Unknown type");
        }

After C# 7.0 

private static void PrintObject(dynamic x)
        {
            if (x is Seller s)
            {
                WriteLine($"Seller Id : {s.Id} Seller Name {s.Name}");
            }
            if (x is Manager m)
            {
                WriteLine($"Manager Id : {m.ManagertId} Manager Name {m.Name}");
            }
            else
                WriteLine("Unknown type");
        }

3. Pattern matching with switch

private static void PrintObject(dynamic x)  
        {  
            switch (x)  
            {  
                case Customer c:  
                    WriteLine($"Customer Id : {c.Id} Customer Name {c.Name}");  
                    break;  
                case Product p:  
                    WriteLine($"Product Id : {p.ProductId} Product Name {p.Name}");  
                    break;  
                default:  
                    WriteLine("Unknown type");  
                    break;  
            }              
        } 


4. switch statement with when condition

private void PrintShapeType(object shape)  
        {  
            switch (shape)  
            {  
                case Triangle t when t.SideA == t.SideB && t.SideB == t.SideC:  
                    WriteLine($"Equilateral Triangle");  
                    break;  
  
                case Triangle t:  
                    WriteLine($"Not a Equilateral Triangle");  
                    break;  
  
                case Rectangle r when r.Height == r.Width:  
                    WriteLine($"Square");  
                    break;  
  
                case Rectangle r:  
                    WriteLine($"Rectangle");  
                    break;  
  
                default:  
                    WriteLine($"Unknow shape");  
                    break;  
            }  
        }  


5. Does Sequence matter for switch


Yes sequence matter first matching case will excute first.


using static System.Console;  
namespace CaseExpressionSequence  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            PrintData(0);  
            PrintData(2);  
            PrintData(5);  
            PrintData(false);  
            PrintData(true);  
            PrintData(55.5);  
        }  
  
        private static void PrintData(object obj)  
        {  
            switch (obj)  
            {  
                case 0:  
                case 5:  
                case true:  
                    WriteLine($"you passed {obj}");  
                    break;  
                case int number:  
                    WriteLine($"you passed a numeric value");  
                    break;  
                case bool b:  
                    WriteLine($"you passed a boolean value");  
                    break;  
                default:  
                    WriteLine($"Invalid data");  
                    break;  
            }  
        }  
    }  
}  


6. Async method returning Task


class Program1
        {
            static void Main(string[] args)
            {                
                PrintPrimeNumbers(100);
                ReadKey();
            }

            private static async Task PrintPrimeNumbers(int maxNumber)
            {
                await Run(() =>
                {
                    WriteLine($"printing prime numbers between 0 and {maxNumber}");
                    List primes = new List();
                    bool isPrime;

                    for (int number = 2; number <= maxNumber; number++)
                    {
                        isPrime = true;
                        foreach (var prime in primes.Where(x => x <= Sqrt(number)))
                        {
                            if (number % prime == 0)
                            {
                                isPrime = false;
                                break;
                            }
                        }
                        if (isPrime)
                        {
                            WriteLine(number);
                            primes.Add(number);
                        }
                    }
                });
            }
        }

7. Same way you can reurn Task

8. Acynch method can return void

9. Async method returning ValueTask

In above example we cna return ValueTask instead of Task because task is frreqence type and we need

10. To use ValueTask, you must need to install NuGet package “System.Threading.Tasks.Extensions”.

11. Async Main (Main Method returning Task)

Main function can return now Task, Task, it may be async also.

12. Can we have more than one Main method in a Project?

Yes  , it is possible in C# 7.0, Main method where you want to start executaion set it in property window startup project

13. Infer Tuple Element Names

// Tuple created without Tuple keyword
class Program  
    {  
        static void Main(string[] args)  
        {  
            var activity = ActivityTracker.GetActivity();  
            WriteLine($"Activity Data: \n Steps: {activity.Item1}\n Distance: {activity.Item2} Km.\n Calories Burned: 

{activity.Item2}\n Sleep Time: {activity.Item4}\n Heart Rate: {activity.Item5}\n Weight: {activity.Item6}");  
        }  
    }  
  
    public class ActivityTracker  
    {  
        public static (int, double, double, TimeSpan, double, double) GetActivity()  
        {  
            int steps = 7000;  
            double distance = 5.2;  
            double caloriesBurned = 30.02;  
            TimeSpan sleepTime = new TimeSpan(6, 20, 00);  
            double heartRate = 72;  
            double weight = 75.5;  
            var activity = (steps, distance, caloriesBurned, sleepTime, heartRate, weight);  
            return activity;  
        }  
    }  

13. Assign a name to every member of tuple

class Program  
    {  
        static void Main(string[] args)  
        {  
            var activity = GetActivity();  
            WriteLine($"Activity Data: \n Steps: {activity.steps}\n Distance: {activity.distance} Km.\n Calories Burned: 

{activity.caloriesBurned}\n Sleep Time: {activity.sleepTime}\n Heart Rate: {activity.heartRate}\n Weight: 

{activity.weight}");  
        }  
    }  
  
    public class ActivityTracker  
    {  
        public static (int steps, double distance, double caloriesBurned, TimeSpan sleepTime, double heartRate, double 

weight) GetActivity() => (steps: 7000, distance: 5.2, caloriesBurned: 30.02, sleepTime: new TimeSpan(6, 20, 00), heartRate: 

72, weight: 75.5);  
    }  


14. Deconstructing Tuple


class Program  
    {  
        static void Main(string[] args)  
        {  
            (int steps, double distance, double caloriesBurned, TimeSpan sleepTime, double heartRate, double weight) = 

GetActivity();  
            WriteLine($"Activity Data: \n Steps: {steps}\n Distance: {distance} Km.\n Calories Burned: {caloriesBurned}\n 

Sleep Time: {sleepTime}\n Heart Rate: {heartRate}\n Weight: {weight}");  
        }  
  
        public static (int steps, double distance, double caloriesBurned, TimeSpan sleepTime, double heartRate, double 

weight) GetActivity() => (steps: 7000, distance: 5.2, caloriesBurned: 30.02, sleepTime: new TimeSpan(6, 20, 00), heartRate: 

72, weight: 75.5);  
    }  

15 Inferring element name of a Tuple


public static void GetActivity()  
 {  
     int steps = 7000;  
     double distance = 5.2;  
     double caloriesBurned = 30.02;  
     TimeSpan sleepTime = new TimeSpan(6, 20, 00);  
     double heartRate = 72;  
     double weight = 75.5;  
     var activity = (steps, distance, caloriesBurned, sleepTime, heartRate, weight);  
  
     WriteLine($"Activity Data: \n Steps: {activity.steps}\n Distance: {activity.distance} Km.");  
 }  



16. Default keyword before C# 7.0

Before C# 7.1
int a = default(int);  
        bool b = default(bool);  
        string c = default(string);  
        int? d = defailt(int?);  

After C# 7.1
int a = default;  
bool b = default;  
string c = default;  
int? d = default;  
Action action = default;  
Predicate predicate = default;  
List list = default;  
Dictionary dictionary = default;  
public int Add(int x, int y = default, int z = default)  
 {  
     return x + y + z;  
 } 



17.Pattern Matching with Generics 


public void PrintProduct(T product) where T:Product  
{  
    switch (product)  
    {  
        case ConvenienceProduct p:  
            WriteLine("Convenience Product");  
            // ---- print other information  
            break;  
        case ShoppingProduct p:  
            WriteLine("Shopping Product");  
            // ---- print other information  
            break;  
  
        case SpecialtyProduct p:  
            WriteLine("Specialty Product");  
            // ---- print other information  
            break;  
        default:  
            WriteLine("General Product");  
            break;  
    }  

public void Print(T type) where T : class  
{  
    switch (type)  
    {  
        case Customer customer:  
            WriteLine($"{customer.Id} {customer.Name} {customer.CustomerType} {customer.MonthlyPurchase}");  
            break;  
        case Product product:  
            WriteLine($"{product.ProductId} {product.ProductName} {product.ProductDescription}");  
            break;  
        default:  
            break;  
    }  


18. in Visual studio 2017 support for inline variable declaration has been added and it also provides intellisence for inline variable declaration with information id “IDE0018”.


19. In C# 7 we can use ‘ref’ for return a variable from a method i.e. a method can return variable with reference.


20. Use ref kyword as a local and return variable

class Program  
    {  
        public ref int GetFirstOddNumber(int[] numbers)  
        {  
            for (int i = 0; i < numbers.Length; i++)  
            {  
                if (numbers[i] % 2 == 1)  
                {  
                    return ref numbers[i]; //returning as reference  
                }  
            }  
            throw new Exception("odd number not found");  
        }  
        static void Main(string[] args)  
        {  
            Program p = new Program();  
            int[] x = { 2, 4, 62, 54, 33, 55, 66, 71, 92 };  
            ref int oddNum = ref p.GetFirstOddNumber(x); //storing as reference  
            WriteLine($"\t\t\t\t{oddNum}");  
            oddNum = 35;  
            for (int i = 0; i < x.Length; i++)  
            {  
                Write($"{x[i]}\t");                  
            }  
            ReadKey();  
        }  
    }  

Output 2 4 62 35 55 66 71 92

So if will update oddNum variable than it will updated in array as well

21. Use ref as a return type

class Program  
    {  
        static void Main(string[] args)  
        {  
            GetEmployee() = new Employee { Id = 2, Name = "Banketeshvar", Age = 28 };  
        }  
    }  
  
    class Employee  
    {  
        public int Id { get; set; }  
        public string Name { get; set; }  
        public int Age { get; set; }  
    }  
  
    class DummyEmployees  
    {  
        public static Employee employee = null;  
        public static ref Employee GetEmployee()  
        {  
            if (employee == null)  
            {  
                employee = new Employee { Id = 1, Name = "Manish Sharma", Age = 27 };  
            }  
            return ref employee;  
        }  
    }  
}   

22. Local functions or nested functions

using static System.Console;  
namespace UseLocalFunctions {  
    class Program {  
        static void Main(string[] args) {  
            void Add(int x, int y) {  
                WriteLine($ "Sum of {x} and {y} is : {x + y}");  
            }  
            void Multiply(int x, int y) {  
                WriteLine($ "Multiply of {x} and {y} is : {x * y}");  
                Add(30, 10);  
            }  
            Add(20, 50);  
            Multiply(20, 50);  
        }  
    }  
}  

It can also return value.
Factoril wihtout recursive function

private static long GetFactorialUsingLocal(int number) {  
    if (number < 0) throw new ArgumentException("negative number", nameof(number));  
    if (number == 0) return 1;  
    long result = number;  
    while (number > 1) {  
        Multiply(number - 1);  
        number--;  
    }  
    void Multiply(int x) => result *= x;  
    return result;  
}  

23. Binary Literals


You can use “0B” or “0b” for binary literal. So, in C# 7, you can represent integer in 3 ways - decimal literal, hexadecimal literal, and binary literal. Before C# 7 there were only two literal allowed decimal and hexa

 int a = 50; // decimal representation of 50  
            int b = 0X32; // hexadecimal representation of 50  
            int c = 0B110010; //binary representation of 50  
            //Represent 100 in decimal, hexadecimal & binary  
            int d = 50 * 2; // decimal represenation of 100   
            int e = 0x32 * 2; // hexadecimal represenation of 100  
            int f = 0b110010 * 2; //binary represenation of 100  

24. Digit Separators

We can use one or more than one Underscore( _ ) character for digit separators. Sometimes, it is required when we are going to represent a big number.

region Using Digit Separators  
            int binaryData = 0B0010 _0111_0001_0000; // binary value of 10000   
            int hexaDecimalData = 0X2B _67; //HexaDecimal Value of 11,111   
            int decimalData = 104 _567_789;  
            int myCustomData = 1 ___________2__________3___4____5_____6;  
            double realdata = 1 _000 .111 _1e1_00;  
            WriteLine($ " binaryData :{binaryData} \n hexaDecimalData: {hexaDecimalData} \n decimalData: {decimalData} \n myCustomData: {myCustomData} \n realdata: {realdata}");#  
            endregion  

25. Pattern matching


var myData = "Custom Data";  
            var myData2 = myData is string ? "String" : "Not a string";  
            var myData3 = myData is string a ? a : "Not a String";  
            WriteLine(myData2);  
            WriteLine(myData3);  
            //Example 2   
            var x = 10;  
            dynamic y = 0b1001;  
            var sum = y is int ? $ "{y * x}" : "Invalid data";  
            WriteLine(sum);  

26. Deconstruction

“deconstruction” is a concept which allows us to access a tuple member directly with its name without using any tuple variable name.


37. Throw Expressions


In C# 7, we can throw an exception directly through expression.
class Program {  
    static void Main(string[] args) {  
        var a = Divide(10, 0);  
    }  
    public static double Divide(int x, int y) {  
        return y != 0 ? x % y : throw new DivideByZeroException();  
    }  
} // This is just a sample script. Paste your real code (javascript or HTML) here.  
if ('this_is' == /an_example/) {  
    of_beautifier();  
} else {  
    var a = b ? (c % d) : e[f];  
}  

Followers

Link