Perfect for anyone wanting to prove their .NET expertise!
Hello .NET Developers,
The article delves into 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.
1. Difference between IEnumerable vs. ICollection
While writing logic in C#, developers frequently encounter IEnumerable and ICollection. They may look quite similar but they serve different purposes in software development.
- IEnumerable acts as the base interface for non-generic collections. It helps to iterate over a collection of a defined type.
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
IEnumerable<int> numbers = new List<int> { 1, 2, 3 };
foreach (var number in numbers) {
Console.WriteLine(number); // Outputs: 1 2 3
}
- ICollection extends IEnumerable 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 when alter methods are required for the collection and IEnumerable for simple read actions.
2. The Role of Dependency Injection in .NET Core
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#
- Register services in the ConfigureServices method of your Startup.cs file. This is where you define which services will be available for injection.
public void ConfigureServices(IServiceCollection services) {
// Register a transient service
services.AddTransient<IMyService, MyService>();
}
- Inject services into your classes through constructor injection. This ensures that your classes receive their dependencies without needing to create them directly.
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.
3. The Difference Between ref and out Parameters
In C#, ref and out are used to pass parameters by reference, but they have distinct characteristics.
- ref parameters require that the variable be initialized before it is passed to a method. The method can then modify the variable’s value.
public void UpdateValue(ref int number)
{
number += 10;
}
int myNumber = 5;
UpdateValue(ref myNumber);
Console.WriteLine(myNumber); // Outputs: 15
- out parameters do not require initialization before being passed. The method must assign a value to the out parameter before it returns.
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.
4. Async and Await: Improving Application Performance
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.
- async methods allow you to perform tasks asynchronously. Mark a method with the async keyword to enable the use of await inside it.
public async Task<string> FetchDataAsync()
{
await Task.Delay(1000); // Simulates an asynchronous operation
return "Data fetched";
}
- await helps application UI by not blocking the main thread.
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.
5. Exception Handling in .NET Core Applications
Handling exceptions gracefully is crucial for maintaining robust and user-friendly applications. .NET Core provides various mechanisms for exception handling.
- Local exception handling: Use try-catch blocks to catch and handle exceptions.
try
{
int result = 10 / 0; // This will throw a DivideByZeroException
}
catch (DivideByZeroException ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
- Global exception handling in ASP.NET Core can be managed using middleware. Catch all types of exceptions in a common place which helps developers to manage user-friendly/common error messages for users.
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.
6. The Role of appsettings.json ASP.NET Core
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
- Example appsettings.json file:
{
"ConnectionStrings": {
"DefaultConnection": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
- Accessing configuration values in your application is straightforward using the built-in configuration system.
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.
7. Understanding Task vs. Thread in C
Both Task and Thread are used for concurrent programming in C#, but they serve different purposes.
- Thread represents a single path of execution and is a lower-level construct. It provides more control over the execution but requires manual management.
Thread thread = new Thread(() =>
{
Console.WriteLine("Running on a new thread");
});
thread.Start();
- Task provides an abstract functionality to implement async operations and is used along with async/await.
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 series here on Medium
So, how did you do?
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!
Top comments (0)