This article is perfect for anyone wanting to prove their .NET expertise!
Hello .NET Developers,
In this article, I’ll explore different C# concepts that every developer must know. It's always a great idea to test your knowledge and I’ve put together a few examples in this article with explanations and code examples.
If you know and understand the code examples, you’re likely doing quite well in the .NET.
While writing logic in C#, developers frequently encounter IEnumerable<T> and ICollection<T>. They may look quite similar but they serve different purposes in software development.
Good to have a lightweight collection which is more secure, as data manipulation is not allowed. Any collection if you want to prevent data manipulation, its recommended to use IEnumerable<T>
IEnumerable<int> numbers = new List<int> { 1, 2, 3 };
foreach (var number in numbers) {
Console.WriteLine(number); // Outputs: 1 2 3
}
ICollection<T> extends IEnumerable<T> allows modifications with the help of alteration methods. This interface consists of methods to add, remove and check counts in the collection.
ICollection<int> data = new List<int> { 12,43,556};
numbers.Add(4);
Console.WriteLine(data.Count); // Outputs: 4
It is recommended to ICollection<T> when alter methods are required for the collection and IEnumerable<T> for simple read actions.
It’s recommended to use a DI design pattern when you want to write loosely coupled & testable code, i. With DI, developers can manage dependencies between classes easily.
.NET Core has built-in support for DI, making it easy to implement.
How a developer can implement DI in C#
public void ConfigureServices(IServiceCollection services) {
// Register a transient service
services.AddTransient<IMyService, MyService>();
}
public class MyController : Controller
{
private readonly IMyService _myService;
public MyController(IMyService myService) { _myService = myService; }
public IActionResult Index() {
var data = _myService.GetData();
return View(data);
}
}
A code is more maintainable and testable when a developer decouples the creation of services.
In C#, ref and out are used to pass parameters by reference, but they have distinct characteristics.
public void UpdateValue(ref int number)
{
number += 10;
}
int myNumber = 5;
UpdateValue(ref myNumber);
Console.WriteLine(myNumber); // Outputs: 15
public void GetValues(out int value1, out int value2)
{
value1 = 10;
value2 = 20;
}
GetValues(out int a, out int b);
Console.WriteLine(a); // Outputs: 10
Console.WriteLine(b); // Outputs: 20
ref is typically used when a method needs to modify an existing variable, while out is used when a method needs to return multiple values or initialize values that were not provided by the caller.
In .NET, asynchronous programming is essential for writing efficient applications that perform well under load. The async and await keywords simplify working with asynchronous operations.
public async Task<string> FetchDataAsync()
{
await Task.Delay(1000); // Simulates an asynchronous operation
return "Data fetched";
}
public async Task ShowDataAsync()
{
string data = await FetchDataAsync();
Console.WriteLine(data);
}
If you want improve performance of your application use async and await effectively and at the same time keeping application UI responsive.
Handling exceptions gracefully is crucial for maintaining robust and user-friendly applications. .NET Core provides various mechanisms for exception handling.
try
{
int result = 10 / 0; // This will throw a DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/Home/Error");
}
Global exception handling middleware provides a common place to handle all application errors and exceptions. It ensures application consistently handles responses.
The appsettings.json file is used for managing application credentials, such as configuration strings and other application-specific keys. The configuration settings can be divided as per environments too
{
"ConnectionStrings": {
"DefaultConnection": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
public class MyService
{
private readonly string _connectionString;
public MyService(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
}
The appsettings.json file allows for easily fetch configuration settings, needs to handled efficiently.
Both Task and Thread are used for concurrent programming in C#, but they serve different purposes.
Thread thread = new Thread(() =>
{
Console.WriteLine("Running on a new thread");
});
thread.Start();
Task.Run(() =>
{
Console.WriteLine("Running asynchronously");
});
Tasks simplify the management of asynchronous operations and are often the preferred choice for modern C# development.
Access the complete C# .Net Interview Series
If you know the concept with confidence and understand the code examples, you’re likely well-versed in .NET.
Let’s keep the conversation going and help each other grow as .NET professionals.
Happy coding!