A comparison table or code snippet demonstrating List vs IEnumerable in C#

List<T> or IEnumerable<T> in C#: Which one to choose?

That classic question: List<T> or IEnumerable<T> in C#? Straight to the point: IEnumerable<T>: when you only need forward iteration. It also works with deferred execution, the basis of LINQ and ideal for handling large amounts of data without loading everything into memory. ICollection<T>: in addition to iteration, it allows you to add, remove, and count items, but without index access. IList<T>: includes everything from ICollection<T>, plus index-based access and the ability to insert/remove at specific positions. List<T>: the concrete implementation of IList<T>, the class you usually use to instantiate a list. Why does this matter? Whenever possible, use the minimal required interface. Clear contracts reduce coupling and make your code more flexible and easier to maintain. ...

November 15, 2025 · 1 min · 125 words · Eduardo Potumati
Semaphore and SemaphoreSlim

Concurrency Control in C#: Semaphore and SemaphoreSlim

I recently published a detailed technical article on Balta.io-one of the premier .NET ecosystem references in Brazil-addressing a critical topic for high-performance systems: concurrency control. As software engineers with extensive experience in high-demand solutions, we often face the challenge of “doing as much as possible, as fast as possible”. However, infrastructure realities-such as rate limits in third-party APIs or hardware constraints-force us to understand exactly when and how to throttle our execution. ...

August 13, 2025 · 2 min · 251 words · Eduardo Potumati
A diagram or code snippet illustrating the Dependency Inversion Principle

Dependency Inversion (D) in SOLID: Why Is It So Important?

Dependency Inversion (D) in SOLID: Why Is It So Important? The Dependency Inversion Principle (D) reminds us that “high-level modules should not depend on low-level modules; both should depend on abstractions.” This means clients (code consuming functionalities) should rely on interfaces or abstractions, not concrete implementations. This practice reduces coupling, simplifies changes, and makes code more testable. For example, instead of directly coupling a notification service to a concrete class like EmailSender, use an interface such as IEmailSender. This allows you to easily swap implementations (e.g., SMTPClient, API service, message queue, etc) without modifying the client. ...

December 15, 2024 · 1 min · 124 words · Eduardo Potumati