C# 7 contains many new features related to data and code optimization.Some of the new and useful features in C# 7 are:
- Tuple types and tuple literals
- Out variables declaration
- Pattern Matching
- Local functions
Tuple types and tuple literals
Tuple class has been introduced in the Framework 4.0.It is is used to group together related values.
If we want to return multiple values from a method then we have different options available:
- define out parameters in the calling method
- define custom data transfer objects
- return dynamic type
But these ways of returning multiple values have some drawbacks:
- If you are using out parameters to return multiple values from a method then you need to pass all the arguments corresponding to the method parameters.This makes it incontinent for the caller of the method.
- Custom data transfer objects means you are creating a class just to return group of values.So the use of class is restricted to grouping a bunch of values temporarily.
- Dynamic type is determined at run time so it has performance overheads.
Tuple is a data structure which contains multiple fields.In the previous versions System.Tuple type was used to create Tuple object as:
var lang= new Tuple<string,int>("C#",7);
C# 7 introduces Tuple types and tuple literals for returning multiple values from a method without having to create Tuples using Create() method as above.
Using Tuple types and tuple literals we can return custom result from a method called Sum as:
(int,int,in) Sum(int a,int b) //this is how we define a tuple type { int add=a+b; int sub=a-b; int mul=a*b; return (add, sub, mult); //this is how we return tuple literal }
caller of the method can call it just like a normal method
var result=Sum(2,4);
caller can access the different values using the name Item1,Item2,…
int add=result.Item1;
int sub=result.Item2;
int mult=result.Item3;
This is simpler approach of returning and accessing multiple return values then the previous approaches.
Out variables
In the previous versions of C# ,we have to first declare out variable and then pass it to the method.So if we want to pass an out variables called a and b in a method called sum then we have to use syntax similar to the following:
int a,b; int result=sum(out a, out b);
in C# 7 the above method call is simplified to
int result=sum(out int a, out int b);
or we can write even simpler form:
int result=sum(out var a, out var b);
Pattern matching
You can use pattern matching to simplify the type conversion and type matching code.In the previous versions you need to verify if a variable is of a particular type using the is operator.Then you have to actually perform the type conversion separately as:
if(obj is Employee) { Employee emp=(Employee)obj; } else if(obj is Contractor) { Contractor cont=(Contractor)obj; }
in C# 7 you can simply write
if(obj is Employee emp) { } else if(obj is Contractor cont) { }
You can use pattern matching to simplify the switch statement.Like the is operator you can declare the variable inline in switch statement.Not only this you can use expressions using the when operator.
In the following example switch statement checks the type of employee.If the employee is having more then 10 years of experience the switch variable is converted to SeniorDeveloper type else it is converted to Developer type.
class Employee { public string designation; public int totalExp; public void doWork() { } } class SeniorDeveloper : Employee { public void MentorDevelopers() { } } class Developer : Employee { public void AttendSkillTrainings() { } }
Local functions
Sometimes you define functions and call it from only one place,from a single method.If you declare such methods then it is difficult to understand the scope of such methods when looking at the code for the first time.In such cases you can define the function inside another function.The nested functions scope is
only the enclosing function.For example you can declare a nested local function as:
static string getFullName(string firstName, string lastName, string middleName) { return concatenateName(); string concatenateName() { string fullName = string.Format("{0} {1} {2}",firstName,middleName,lastName); return fullName; } }
The method concatenateName is a local function here.The variable fullName is available only inside concatenateName and is not available outside it.
Non-Nullable Reference Types
You can normally assign a null value to reference types.For example you can assign a null value to a string:
string name=null;
though assigning null values to reference types is useful ,it is also a source of runtime exceptions many times.If you write the following:
int len= name.Length;
the above line will throw exception if name is null.
In C# 7 you can specify that a reference is non nullable. So when declaring a reference you can declare a non nullable reference as:
string! name;
Now the reference name is guaranteed to be non null.So you can call method on the name variable without being concerned about the run time exceptions:
int len= name.Length;
Leave a Reply