C# is a modern, object-oriented programming language developed by Microsoft. It was first introduced in 2002 as part of Microsoft’s .NET framework. It is a simple, powerful, and type-safe programming language used to build desktop, web, game, and mobile applications. It supports both static and dynamic typing. It is a very versatile programming language that is continuously evolving. Therefore, a .NET or a C# developer must remain up to date with the changes. Here is the list of the awesome features that you should know: 1. GenericsGenerics introduces the concept of type parameters to .NET, which makes it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. It is commonly used to create collection classes. The .NET class library contains several generic collection classes in the System.Collections.Generic namespace. You can create your generic interfaces, classes, methods, events, and delegates. This feature was introduced in C# 2.0. Example
// Declare the generic class.
public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("");
// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}
By using a generic type parameter T, you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations Read More - C# Interview Questions For Freshers 2. Partial ClassThis feature was introduced in C# 2.0. To split a class definition across multiple files, use the partial keyword modifier. When working with an automatically generated source, code can be added to the class without having to recreate the source file. The partial keyword indicates that other parts of the class, struct, or interface can be defined in the namespace. All the parts must use the partial keyword. All the parts must be available at compile time to form the final type. All the parts must have the same accessibility, such as public, private, and so on.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
In the above code, the fields and the constructor of the class, Coords, are declared in one partial class definition, and the member, PrintCoords, is declared in another partial class definition. OutputCoords: 10,15
3. LINQ: Language Integrated QueryIt was introduced in the C# 3.0 version. Allows to query various data sources like C# collection, SQL, and XML-like data using common query syntax. - LINQ to Objects
LINQ can be used to query in-memory objects and collections. It provides a set of standard query operators that operate on collections implementing IEnumerable. using System;
using System.Linq;
using System.Collections.Generic;
class Program
{ static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
Output
2
4
- LINQ to SQL
LINQ to SQL allows querying relational databases using LINQ. It involves mapping database tables to C# classes and writing queries in a LINQ syntax. using System;
using System.Linq;
class Program
{ static void Main()
{
// Assume a DataContext and a 'Products' table mapping to a C# class
using (var context = new MyDataContext())
{
var expensiveProducts = from product in context.Products
where product.Price > 50
select product;
foreach (var product in expensiveProducts)
{
Console.WriteLine($"{product.Name} - {product.Price}");
}
}
}
}
Output
ProductA - 75
ProductB - 60
ProductC - 55
- LINQ to XML
LINQ to XML enables querying and manipulating XML data using LINQ. It allows you to express queries against XML documents naturally. using System;
using System.Linq;
using System.Xml.Linq;
class Program
{ static void Main()
{
XElement root = XElement.Load("books.xml");
var bookTitles = from book in root.Elements("book")
select book.Element("title").Value;
foreach (var title in bookTitles)
{
Console.WriteLine(title);
}
}
}
Output
Book Title 1
Book Title 2
Book Title 3
4. Lambda ExpressionsC# Lambda Expression is a short block of code that accepts parameters and returns a value. It is defined as an anonymous function i.e. a function without a name. It was introduced in C# 3.0. Provides a concise way to write inline expressions or anonymous methods. They are often used with LINQ queries or as a convenient way to define delegates or event handlers. Syntax(parameterList) => lambda body
Here, - parameterList - list of input parameters
- \=> - a lambda operator
- lambda body - can be an expression or statement
Example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
0 Example of Writing Easy and Simple Delegate Code Using Lambda Expression
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
1 In the above code, we don't need to define a separate method. We have replaced the pointer to the square() method with the lambda expression. Output
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
2 5. Extension MethodsThis feature has been added in C# 3.0. It allows us to add new methods into a class without editing the source code of the class i.e. extending the functionality of a class in the future if the source code of the class is not available or we don’t have any permission to make changes to the class. Example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
3 Let’s create a new class with the name NewClass.cs and then copy and paste the following code into it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
5 Output
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
6 6. Dynamic TypeThe Dynamic Type is introduced as part of C# 4 to write dynamic code in C#. It defers type checking from compile time to runtime. Method calls and property accesses are resolved at runtime, which can lead to performance overhead. It is advantageous when you want to avoid typecasting and interacting with dynamic languages like Python, and JavaScript.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
7 Output
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
8 7. Async/AwaitAsync and Await introduced in C# 5.0 are the code markers that mark code positions from where the control should resume after completing a task. It helps to write asynchronous code, which is essential for non-blocking UI and server applications. Example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Hello
{
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
9 In the code above, Method1 and Method2 are not dependent on each other, and we call from the Main method. We can see that Method1 and Method2 are not waiting for each other. 8. String InterpolationIt was introduced in C# 6.0. It allows you to embed expressions and variables directly within string literals. It provides a concise and more readable way to create formatted strings compared to traditional string concatenation or the String.Format method. ExampleCoords: 10,15
0 OutputCoords: 10,15
1 9. Expression-Bodied MembersExpression-bodied members are a syntactic shorthand introduced in C# 6.0. They allow you to write concise one-liner methods, properties, and other members using lambda-like syntax. They can be used for methods, properties, indexers, and event accessors. ExampleCoords: 10,15
2 OutputCoords: 10,15
3 10. Auto-Property InitializersAuto-property initializers provide a way to initialize the value of an auto-implemented property directly within the property declaration. This simplifies the syntax for setting default values for properties. They were introduced in C# 6.0. Auto-property initializers are a concise way to set default values for properties, and they are particularly useful for avoiding the need to initialize properties in the constructor. ExampleCoords: 10,15
4 OutputCoords: 10,15
5 11. Tuples and DeconstructionTuples and Deconstruction are features introduced in C# 7.0 that provide convenient ways to work with sets of values. - Tuples
Tuples allow you to group multiple values into a single object without the need to create a custom class or struct. One can use either named or unnamed tuples. - Unnamed Tuples
Coords: 10,15
6 - Named Tuples
Coords: 10,15
7
- Deconstruction
Deconstruction allows you to split a tuple or any other object into its components. Coords: 10,15
8
12. Pattern MatchingPattern matching is a feature introduced in C# 7.0 that allows you to check the shape or structure of a value directly in code. It simplifies the syntax for common type checks and extractions, making code more readable and reducing boilerplate code. Example of Type PatternCoords: 10,15
9 Output
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
0 13. Nullable Reference TypesNullable Reference Types is a feature introduced in C# 8.0 to help developers write more robust and safe code by adding annotations to the type system to indicate whether a reference type can be null or not. It allows you to express the intent about nullability directly in the code, and the compiler can provide warnings for potential null-reference issues. Enabling Nullable Reference Types 14. Default Interface MethodsIntroduced in C# 8.0 the methods allow you to provide a default implementation for methods in an interface. This feature helps maintain backward compatibility when introducing new methods to an interface without requiring all implementing classes to provide an implementation. It is useful when you want to extend existing interfaces without breaking existing implementations.
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
1 Output
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
2 15. Record TypesRecord types feature was introduced in C# 9.0 to provide a concise way to declare immutable types. Records simplify the process of creating and working with immutable classes by automatically generating common methods like Equals, GetHashCode, and ToString. They are particularly useful for modeling data transfer objects (DTOs) and other types where immutability and value equality are essential.
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
3 Output
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
4 16. Top-Level StatementsIntroduced in C# 9.0 it allows you to write simpler C# programs by omitting the traditional Main method and placing the program logic directly at the top level of the file. It simplifies the structure of simple programs by reducing boilerplate code.
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
5 Output
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
6 17. Global Using DirectivesThe global using directives feature was introduced in C# 10.0. It allows you to specify a set of using directives that will be applied globally to all files in a project without the need to include them explicitly in every file. This can help reduce the boilerplate code in your files and provide a more consistent and simplified coding experience. Example
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
7 Output
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
8 18. List PatternsList patterns in C# are a type of pattern introduced in C# 9.0 to match elements of a list or array succinctly and expressively. They provide a concise way to destructure and match the elements of a list or array. Example
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List numbers = new List { 1, 2, 3, 4, 5 };
// LINQ query to filter even numbers
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
foreach (var evenNumber in evenNumbers)
{
Console.WriteLine(evenNumber);
}
}
}
9 Output2
4
0 19. required modifierWhenever a class is declared with a property or field with the required keyword, the caller is forced to initialize in the object initializer scope. It was introduced in C# 11 Example2
4
1 20. Collection Expressions A collection expression is a terse syntax that, when evaluated, can be assigned to many different collection types. It contains a sequence of elements between [ and ] brackets. It can be converted to many different collection types. Example2
4
2 The above code declares a System.Span of string elements and initialize them to the days of the week. SummaryHence, we have beautifully listed out the top 20 C# features required to be known by aspiring as well as experienced C# or .NET developers. Go through the complete article thoroughly and make the most out of it. To become a Certified .NET Developer, consider our .NET Training. FAQs
Q1. What is the use of partial keyword in C#?The partial keyword indicates that other parts of the class, struct, or interface can be defined in the namespace. Q2. What are Lambda Expressions in C#?Lambda Function is defined as an anonymous function i.e. a function without a name. Q3. What are Auto-Property Initializers?Auto-property initializers provide a way to initialize the value of an auto-implemented property directly within the property declaration. This simplifies the syntax for setting default values for properties. Take our free csharp skill challenge to evaluate your skill In less than 5 minutes, with our skill challenge, you can identify your knowledge gaps and strengths in a given skill. What are the new iOS 17 features?What's new in iOS 17. StandBy. Turn your iPhone on its side while charging to glance at important information from a distance. ... . Interactive widgets. Widgets on your Home Screen, Lock Screen, and StandBy are even more useful with interactivity. ... . Contact Posters. ... . Live Voicemail. ... . Stickers. ... . Journal. ... . Messages. ... . Keyboard.. How is iOS 17 better?Apple iOS 17 Specs However, AirDrop, Messages, Notes, Safari, voicemail, security, and numerous other features get notable enhancements that result in an impressively polished, useful, and entertaining iPhone experience. For its many improvements, iOS 17 earns our Editors' Choice award for mobile operating systems.nullApple iOS 17 - Review 2024 - PCMag UKuk.pcmag.com › ios › apple-ios-17null Is one UI 6 available for A52s 5G?Galaxy A52s 5G finally gets Android 14-based One UI 6.0 update in India. The Android 14-based One UI 6.0 update for the Galaxy A52s 5G is now available in India. The update comes with firmware version A528BXXU5FWK4, which has a download size of around 2.32GB.nullSamsung Galaxy A52s gets Android 14 (One UI 6.0) update in Indiawww.sammobile.com › newsnull |