Top 10 C# Keywords and Features
This article explores the top 10 C# keywords and features that every developer should know to use the full potential of the language.
Join the DZone community and get the full member experience.
Join For FreeThe language C# stands out as the top 5th programming language in a Stack Overflow survey. It is widely used for creating various applications, ranging from desktop to mobile to cloud native. With so many language keywords and features it will be taxing to developers to keep up to date with new feature releases. This article delves into the top 10 C# keywords every C# developer should know.
1. Async and Await
- Keywords:
async
,await
The introduction of async
and await
keywords in C# make it easy to handle asynchronous programming in C#. They allow you to write code that performs operations without blocking the main thread. This capability is particularly useful for tasks that are I/O-bound or CPU-intensive. By making use of these keywords, programmers can easily handle long-running compute operations like invoking external APIs to get data or writing or reading from a network drive. This will help in developing responsive applications and can handle concurrent operations.
Example
public async Task<string> GetDataAsync()
{
using (HttpClient client = new HttpClient())
{
string result = await client.GetStringAsync("http://bing.com");
return result;
}
}
2. LINQ
- Keywords:
from
,select
,where
,group
,into
,order by
,join
LINQ (Language Integrated Query) provides an easy way to query various data sources, such as databases, collections, and XML, directly within C# without interacting with additional frameworks like ADO.NET, etc. By using a syntax that is identical to SQL, LINQ enables developers to write queries in a readable way.
Example
var query = from student in students
where student.Age > 18
orderby student.Name
select student;
3. Properties
Properties are mainly members that provide a flexible mechanism to read, write, or compute the value of a private field. Generally, we hide the internal private backing fields and expose them via a public
property. This enables data to be accessed easily by the callers. In the below example, Name
is the property that is hiding a backing field called name
, marked as private
to avoid outside callers modifying the field directly.
Example
class Person
{
private string name; // backing field
public string Name // property
{
get { return name; }
set { name = value; }
}
}
class Program
{
static void Main(string[] args)
{
Person P1 = new Person();
P1.Name = "Sunny";
Console.WriteLine(P1.Name);
}
}
4. Generics
- Keywords:
generic
,<T>
Generics allows you to write the code for a class without specifying the data type(s) that the class works on. It is a class that allows the user to define classes and methods with a placeholder. The introduction of Generics in C#2.0 has completely changed the landscape of creating modular reusable code which otherwise needs to be duplicated in multiple places. Imagine you are handling the addition of 2 numbers that are of int
and then comes a requirement to add float
s or double
datatypes. We ended up creating the same duplicate code because we already defined a method with int
datatypes in the method parameters. Generics makes it easy to define the placeholders and handle logic for different datatypes.
Example
public class Print
{
// Generic method which can take any datatype as method parameter
public void Display<T>(T value)
{
Console.WriteLine($"The value is: {value}");
}
}
public class Program
{
public static void Main(string[] args)
{
Print print = new Print();
// Call the generic method with different data types
print.Display<int>(10);
print.Display<string>("Hello World");
print.Display<double>(20.5);
}
}
5. Delegates and Events
- Keywords:
delegate
,event
A delegate is nothing but an object that refers to a method that you can invoke directly via delegate
without calling the method directly. Delegates are equivalent to function pointers in C++. Delegates are type-safe pointers to any method. Delegates are mainly used in implementing the call-back methods and for handling events. Func<T>
and Action<T>
are inbuilt delegates provided out of the box in C#.
Events, on the other hand, enable a class or object to notify other classes or objects when something of interest occurs. For example, think of a scenario where a user clicks a button on your website. It generates an event (in this case button click) to be handled by a corresponding event handler code.
Examples
Example code for declaring and instantiating a delegate
:
public delegate void MyDelegate1(string msg); // declare a delegate
// This method will be pointed to by the delegate
public static void PrintMessage(string message)
{
Console.WriteLine(message);
}
public static void Main(string[] args)
{
// Instantiate the delegate
MyDelegate1 del = PrintMessage;
// Call the method through the delegate
del("Hello World");
}
Example code for initiating an event and handling it via an event
handler:
// Declare a delegate
public delegate void Notify();
public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // Declare an event
public void StartProcess()
{
Console.WriteLine("Process Started!");
// Some actual work here..
OnProcessCompleted();
}
// Method to call when the process is completed
protected virtual void OnProcessCompleted()
{
ProcessCompleted?.Invoke();
}
}
public class Program
{
public static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += bl_ProcessCompleted; // Register event handler
bl.StartProcess();
}
// Event handler
public static void bl_ProcessCompleted()
{
Console.WriteLine("Process Completed!");
}
}
6. Lambda Expressions
- Keyword:
lambda
,=>
Lambda expressions provide an easy way to represent methods, particularly useful in LINQ queries and for defining short inline functions. This feature allows developers to write readable code by eliminating the need for traditional method definitions when performing simple operations. Lambda expressions enhance code clarity and efficiency by making them an invaluable tool for developers when working with C#.
Example
Func<int, int, int> add = (x, y) => x + y;
int result = add(3, 4); // result is 7
7. Nullable Types
- Keyword:
?
In C#, nullable types allow value types to have a null
state, too. This comes in handy when you're working with databases or data sources that might have null
values. Adding a ?
after a value type helps developers handle cases where data could be missing or not defined. This prevents in causing potential errors when the code is running. This feature makes applications more reliable by giving a clear and straightforward way to handle optional or missing data.
Example:
int? num = null;
if (num.HasValue)
{
Console.WriteLine($"Number: {num.Value}");
}
else
{
Console.WriteLine("No value assigned.");
}
8. Pattern Matching
- Keywords:
switch
,case
Pattern matching is another useful feature introduced in C# 7.0 which then underwent a series of improvements in successive versions of the language. Pattern matching takes an expression and it helps in testing whether it matches a certain criteria or not. Instead of lengthy if-else
statements, we can write code in a compact way that is easy to read. In the below example, I have used object
where I assigned value 5
(which is of int
datatype), which then uses pattern matching to print which datatype it is.
Example
object obj = 5;
if (obj is int i)
{
Console.WriteLine($"Integer: {i}");
}
switch (obj)
{
case int j:
Console.WriteLine($"Integer: {j}");
break;
case string s:
Console.WriteLine($"String: {s}");
break;
default:
Console.WriteLine("Unknown type.");
break;
}
9. Extension Methods
- Keyword:
this
(in method signature)
Extension methods allow developers to add new methods to existing types without changing their original code. These methods are static but work like instance methods of the extended type, offering a smooth way to add new functionality. Extension methods make code more modular and reusable giving developers the ability to extend types from outside libraries without messing up with the original code. Extension methods also support the "Open/Closed" principle, which means code is open to extension but closed to modifications.
Example
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
}
// Usage
string str = null;
bool result = str.IsNullOrEmpty(); // result is true
10. Tuples
- Keyword:
tuple
Tuples let you group multiple values into one single unit. They help when you want to send back more than one value from a method without using out parameters or making a new class only for the purpose of transferring data between objects. With tuples, you can package and return a set of related values, which makes our code easier to read and understand. You can give names to the fields in tuples or leave them unnamed. You then refer to the values using Item1
and Item2
as shown below.
Example
public (int, string) GetPerson()
{
return (1, "John Doe");
}
// Usage
var person = GetPerson();
Console.WriteLine($"ID: {person.Item1}, Name: {person.Item2}");
Conclusion
By using async
/await
to handle tasks well, LINQ to get data, Properties
to keep data safe, Generics
to make sure the types are right, Delegates
and Events
for programs that react to events, Lambda expressions to write short functions, nullable types to deal with missing info, pattern matching to make code clearer and say more, extension methods to add new features, and tuples to organize data well, you can write code that's easier to manage and less likely to break. When you get good at using these features, you'll be able to build responsive, scalable, and top-notch applications. Happy Coding!!!
Opinions expressed by DZone contributors are their own.
Comments