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
}
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");
d. Use Discard in Pattern Matching
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();
}
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];
}