Preface
It seems like only yesterday we got C# 6, it all happens quickly in software development land. And now you are seeing C# 7.0. Jeez, it has more cool features than C# 6.0 and damn sure after going through these you will also be on my side waiting for that one fine day.
For Trying C# 7.0 you need to do the following
- Visual Studio 15 preview
- Set __DEMO__ and__DEMO_EXPERIMENTAL__ as Conditional compilation symbol in project settings.
Feature List in C# 7.0
- Local functions – code available currently in github
- Tuple Types and literals
- Record Types
- Pattern matching
- Non Nullable reference types
- Immutable types
Local Functions
Upto C# 6.0
Ability to declare methods and types in block scope as like variables. It is already possible in current version of C# using Func and Action types with anonymous methods, but they lack these features.
- Generics
- Ref and out
- Params
We can’t utilize these three features while using Func and Action.
In C# 7.0
Local functions would have the same capabilities as normal methods but they can be only accessed within the block they were declared in.
- public int Foo(int someInput)
- {
- int Bar()
- {
- Console.WriteLine(“inner function”);
- }
- return Bar();
- }
- The syntax is similar and more consistent with the methods.
- Recursion and forward references would work for the local functions but not for the lambda.
- The lambda causes one or two memory allocations (the frame object for holding the variables inside that function and a delegate); but local function causes no memory allocations.
- A local function can be generic.
- It can accept ref and out parameters.
- The direct method invocation is indeed faster than a delegate invocation.
Tuple Types and literals
Multiple return types – up to C# 6.0
In our current version of C# for returning multiple values from a method we have follow on of these methods.
- Out parameters
- Tuple-Types
- Class/ Struct
The most common reason for grouping up of temporary variables is to return multiple values from a method.
Out parameters
- public void GetMultipleValues(string deptName, out double topGrossSalary, out string hrName) { ... }
- double gross,
- string hrName;
- GetMultipleValues (name, out gross, out hrName);
- Console.WriteLine($"Gross: { gross }, Hr: { hrName }");
Tuple-Types
Currently, C# has tuple type in order to hold multiple non related values together. We can rewrite the same method to use tuples to achieve the same functionality.
- public Tuple<double, string> GetMultipleValues(string name) { ... }
- var tupleSalary = GetMultipleValues (name);
- Console.WriteLine($"Gross: { tupleSalary.Item1 }, Hr: { tupleSalary.Item2 }");
Class / struct
You could also declare a new type and use that as the return type.
- Struct TopSalaryAndHr { public double topGrossSalary; public string hrName;}
- public TopSalaryAndHr GetMultipleValues(string name) { ... }
- var tupleSalary = GetMultipleValues (name);
- Console.WriteLine($"Gross: { tupleSalary.topGrossSalary }, HR: { tupleSalary.hrName }");
All three ways mentioned above has their own disadvantages, so they want to overcome these shortcomings by introducing a miracle.
Multiple return types in C# 7.0
Tuple return types:
You can specify multiple return types for a function, in much the same syntax as you do for specifying multiple input types. These are supposed to be called Tuple Types.
- Public (double topGrossSalary,string hrName) GetMultipleValues(string name) {……….. }
- public async Task<(double topGrossSalary, string hrName)> GetMultipleValues Async(string name) { ... }
- var t = await GetMultipleValues (myValues);
- Console.WriteLine($"Sum: {t.sum}, count: {t.count}");
Tuple values could be created as,
- var t = new (int sum, int count) { sum = 0, count = 0 };
- public (int sum, int count) Tally(IEnumerable<int> values)
- {
- var s = 0; var c = 0;
- foreach (var value in values) { s += value; c++; }
- return (s, c); // target typed to (int sum, int count)
- }
Using named arguments as a syntax analogy it may also be possible to give the names of the tuple fields directly in the literal:
- public (int sum, int count) Tally(IEnumerable<int> values)
- {
- var res = (sum: 0, count: 0); // infer tuple type from names and values
- foreach (var value in values) { res.sum += value; res.count++; }
- return res;
- }
We don’t need to the tuple object as a whole because it doesn’t represent a particular entity or a thing, so the consumer of a tuple type doesn’t want to access the tuple itself, and instead he can access the internal values of the tuple.
Instead of accessing the tuple properties as in the example of Tuple Return Types, you can also de-structure the tuple immediately:
- (var sal, var hrName) = GetMultipleValues("some address");
- Console.WriteLine($"Salary: { sal }, Hr Name: {hrName}");
Is Expression
The “is” operator can be used to test an expression against a pattern. As part of the pattern-matching feature repurposing the “is” operator to take a pattern on the right-hand-side.
- relational_expression : relational_expression 'is' pattern;
Pattern
Patterns are used in the is operator and in a switch_statement to express the shape of data against which incoming data is to be compared.
There are many areas where we can use patterns in c#. You can do pattern matching on any data type, even your own, whereas if/else you always need primitives to match. Pattern matching can extract values from your expression.
For ex: I am having handful of types
- class Person(string Name);
- class Student(string Name, double Gpa) : Person(Name);
- class Teacher(string Name, string Subject) : Person(Name);
- //This sample uses the latest c# feature record type to create objects
- static string PrintedForm(Person p)
- {
- Student s;
- Teacher t;
- if ((s = p as Student) != null && s.Gpa > 3.5)
- {
- return $"Honor Student {s.Name} ({s.Gpa})";
- }
- else if (s != null)
- {
- return $"Student {s.Name} ({s.Gpa})";
- }
- else if ((t = p as Teacher) != null)
- {
- return $"Teacher {t.Name} of {t.Subject}";
- }
- else
- {
- return $"Person {p.Name}";
- }
- }
- static void Main(string[] args)
- {
- Person[] oa = {
- new Student("Einstein", 4.0),
- new Student("Elvis", 3.0),
- new Student("Poindexter", 3.2),
- new Teacher("Feynmann", "Physics"),
- new Person("Anders"),
- };
- foreach (var o in oa)
- {
- Console.WriteLine(PrintedForm(o));
- }
- Console.ReadKey();
- }
As part of the pattern-matching feature we are repurposing the “is” operator to take a pattern on the right-hand-side. And one kind of pattern is a variable declaration. That allows us to simplify the code like this,
- static string PrintedForm(Person p)
- {
- if (p is Student s && s.Gpa > 3.5) //!
- {
- return $"Honor Student {s.Name} ({s.Gpa})";
- }
- else if (p is Student s)
- {
- return $"Student {s.Name} ({s.Gpa})";
- }
- else if (p is Teacher t)
- {
- return $"Teacher {t.Name} of {t.Subject}";
- }
- else
- {
- return $"Person {p.Name}";
- }
- }
- static string PrintedForm(Person p)
- {
- switch (p) //!
- {
- case Student s when s.Gpa > 3.5 :
- return $"Honor Student {s.Name} ({s.Gpa})";
- case Student s :
- return $"Student {s.Name} ({s.Gpa})";
- case Teacher t :
- return $"Teacher {t.Name} of {t.Subject}";
- default :
- return $"Person {p.Name}";
- }
- }
Record Types
Record Types is concept used for creating a type with only properties. By using that we can embed the constructor declaration with the class declaration.
For ex:
- Class Student(string Name, int Age);
- Class Student
- {
- string _name;
- int _age;
- public Person(string Name, int Age)
- {
- this.Name = Name;
- this.Age = Age;
- }
- public string Name {get{ return this._name;}}
- public int Age {get{ return this._age;}}
- }
- Read-only properties, thus creating it as immutable type.
- The class will automatically implement Equality implementations like (such as GetHashCode, Equals, operator ==, operator != and so forth).
- A default implementation of ToString() method.
Non-Nullable reference types:
Non- nullable reference option will let you create a reference type that is guaranteed not to be null. NullReference expections are too common in a project. Often we developers forgot to check a reference type for null before accessing the properties of it, thus paving way to problems.
Either we forget check for it making our code vulnerable to runtime exceptions or we will check for it which makes our code more verbose.
Instead of using the “?” for identifying the nullable value type we are going to use “!”.The currently proposed syntax is as follows:
- int a; //non-nullable value type
- int? b; //nullable value type
- string! c; //non-nullable reference type
- string d; //nullable reference type
- MyClass a; // Nullable reference type
- MyClass! b; // Non-nullable reference type
- a = null; // OK, this is nullable
- b = null; // Error, b is non-nullable
- b = a; // Error, a might be null, b can't be null
- WriteLine(b.ToString()); // OK, can't be null
- WriteLine(a.ToString()); // Warning! Could be null!
- if (a != null) { WriteLine(a.ToString); } // OK, you checked
- WriteLine(a!.Length); // Ok, if you say so
- It would be quite problematic using the same syntax for generic types and collections. For example
- // The Dictionary is non-nullable but string, List and MyClass aren't
- Dictionary<string, List<MyClass>>! myDict;
- // Proper way to declare all types as non-nullable
- Dictionary<string!, List<MyClass!>!>! myDict;
- // Typing ! in front of the type arguments makes all types non-nullable
- Dictionary!<string, List<MyClass>> myDict;
An immutable object is an object whose state cannot be changed after its creation, which means Immutable objects are objects which once loaded cannot be changed / modified by any way external or internal.
Immutable objects offer few benefits,
- Inherently thread-safe.
- Easier to parallelize.
- Makes it easier to use and reason about code.
- Reference to immutable objects can be cached, as they won’t change.
Currently it is also possible to create immutable classes. Create a class with properties only with get and read-only and constant private variables.
- Public class Point
- {
- public Point(int x, int y)
- {
- x = x;
- Y = y;
- }
- public int X { get; }
- public int Y { get; }
- }
The proposed syntax for creating an immutable class will force the developer to strictly adhere the rules hence will make the class an immutable. Below is the proposed syntax,
- public immutable class Point
- {
- public Point(int x, int y)
- {
- x = x;
- Y = y;
- }
- public int X { get; }
- public int Y { get; }
- }

Jim LorinserPosted Jul 25, 2017, 9:57 AM
Thanks Sarva! Once I read your article, I referred to it more than once, hope to get a new one from you in the nearest future ;) But now I'd like to add it with a couple of useful features in C#7.1 I found out: Asynchronous Main - main could be void or int and contain arguments as a string array and Default Literal - Visual Basic and C# have similar features, but there are certain differences in the languages, i.e. C# has null, while VB.NET has Nothing. In case someone wants to look at code samples, you can find them here - http://codingsight.com/new-features-c-expected-soon/
Ammar ShaukatPosted Apr 29, 2017, 7:06 AM
I'm having problem in using Record types . is there any additional assembly required to use them ?
Bassam AlugiliPosted Feb 23, 2017, 11:11 AM
Thank you for your Explanation!I have summarized the new Features in a cheat sheet (C# 7.0 New Features): </br> https://github.com/alugili/CSharp7Features/blob/master/C#7CheatSheet.pdf
Joe WilsonPosted Jan 15, 2017, 6:29 AM
Well, Thank you for sharing.
Balakrishnan GPosted Jan 3, 2017, 12:07 AM
Very Nice Bro .Its very helpful to me .Thank u very much bro
Sarva RaghavanPosted Sep 8, 2016, 4:23 AM
You can try out most of these features in Visual Studio 2015 Update 4. Link for Visual Studio 2015 Update 4 - https://www.microsoft.com/en-in/download/details.aspx?id=39305
Karthik ElumalaiPosted Sep 3, 2016, 11:06 AM
Good info. Thanks for sharing
Abhishek KumarPosted Sep 3, 2016, 10:21 AM
Nice article
Guest UserPosted Sep 2, 2016, 10:14 PM
Nice article. Its good to learn multiple return values and immutable keyword.
Mahesh ChandPosted Sep 2, 2016, 12:23 PM
C# 7.0 is available now as a part of Visual Studio "15" Update 4.
Atul KumarPosted Jun 3, 2016, 12:45 PM
wow! so many cool features have been added in C#. Thanks for this collection!
Mohammed AshrafPosted May 30, 2016, 4:43 AM
Nice one..
Abhishek KumarPosted May 28, 2016, 10:18 AM
nice article
Prafulla SahuPosted May 25, 2016, 12:40 AM
Thank you so so so much
Thiruppathi RPosted May 20, 2016, 1:48 AM
Needful Info...
Sabyasachi MishraPosted May 20, 2016, 12:20 AM
very inormative
Pradeep SahooPosted May 18, 2016, 4:49 PM
Nice share .........
Tk MahantaPosted May 9, 2016, 2:48 AM
Nice feature..
Humayun Kabir MamunPosted May 9, 2016, 2:08 AM
Nice...
Manish Kumar ChoudharyPosted May 8, 2016, 11:15 AM
Nice one
Sabyasachi MishraPosted May 7, 2016, 3:33 AM
Good one and very informative.
Vipan SharmaPosted May 7, 2016, 3:08 AM
thnx
Neeraj KumarPosted May 6, 2016, 4:29 PM
Nice share...
Sr KarthigaPosted May 6, 2016, 3:44 AM
good one
NitinPosted May 6, 2016, 3:27 AM
very good information. thanks for sharing
Sibeesh VenuPosted May 6, 2016, 1:46 AM
I really loved your article, thanks much. The one thing I found missing is the conclusion part.
Jaipal ReddyPosted May 6, 2016, 12:14 AM
Nice. .
Amit Kumar SinghPosted May 5, 2016, 4:23 PM
Nice one
Anbu ManiPosted May 5, 2016, 1:32 PM
Nice one
Sarva RaghavanPosted May 5, 2016, 1:07 PM
Thanks for the compliment guys.. This is my first one.. Please let me know pitfalls or shortcomings will try to avoid that in my future articles
Kuppurasu NagarajPosted May 5, 2016, 1:07 PM
Nice Sharing..
sreenivasa kPosted May 5, 2016, 10:52 AM
nice
Pankaj Kumar ChoudharyPosted May 5, 2016, 9:42 AM
Nice Explanation..........
Debasis SahaPosted May 5, 2016, 9:41 AM
Good one..
Raja TPosted May 5, 2016, 9:21 AM
Nice, Thanks for sharing
Vignesh ManiPosted May 5, 2016, 8:21 AM
Good start.
Sarva RaghavanPosted May 5, 2016, 7:36 AM
Thanks Dinesh
Dinesh BeniwalPosted May 5, 2016, 6:17 AM
Welcome to C# Corner Sarva