<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[C# .NET: Exploring Software Design and Architecture || Sushant Pant]]></title><description><![CDATA[Mostly about C#, .NET, Software Design and Distributed system.]]></description><link>https://sushantpant.com.np</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 01:50:20 GMT</lastBuildDate><atom:link href="https://sushantpant.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Pub-sub pattern]]></title><description><![CDATA[In my previous articles, we built a messaging system using RabbitMQ. One limitation of that approach was that each message was delivered to only one consumer. For instance, if we had two consumers promotional.Email and promotional.Sms there would be ...]]></description><link>https://sushantpant.com.np/pub-sub-pattern</link><guid isPermaLink="true">https://sushantpant.com.np/pub-sub-pattern</guid><category><![CDATA[PubSub]]></category><category><![CDATA[SignalR]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[.NET]]></category><category><![CDATA[websockets]]></category><category><![CDATA[distributed system]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Sun, 25 Aug 2024 10:15:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723307924898/eb638770-0f34-4201-97e5-af0fa17f1ac2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my <a target="_blank" href="https://sushantpant.com.np/messaging-queuing-technologies">previous articles</a>, we built a messaging system using RabbitMQ. One limitation of that approach was that each message was delivered to only one consumer. For instance, if we had two consumers <code>promotional.Email</code> and <code>promotional.Sms</code> there would be two separate queues. That means, if we add <em>n</em> number of promotional consumer there would <em>n</em> number of queues. Another drawback of message queue was, publisher requires explicit routing to a specific consumers. This means that the publisher must know the exact queue or exchange a consumer is bound to. Instead of this setup, we'll now build a system where the publisher can send a message to multiple consumers simultaneously. This is known as the pub-sub (publish-subscribe) pattern. Here's how it can be visualized:</p>
<p><img src="https://d1.awsstatic.com/product-marketing/Messaging/sns_img_topic.e024462ec88e79ed63d690a2eed6e050e33fb36f.png" alt class="image--center mx-auto" /></p>
<p><em>Diagram source:</em> <a target="_blank" href="https://aws.amazon.com/what-is/pub-sub-messaging/"><em>aws</em></a></p>
<h2 id="heading-introduction">Introduction</h2>
<p>As the name suggests, "pub-sub" its an architectural pattern where a publisher sends out messages, and subscribers receives them. The cool part is that the publisher doesn't need to know who the subscribers are or how many of them are receiving the message. There are some terms to understand in pub sub:</p>
<p><strong>Publisher:</strong> The entity that publishes message.</p>
<p><strong>Message:</strong> Data published (sent) by publisher.</p>
<p><strong>Topic:</strong> A central hub to manage similar queues. Subscribers of topic will receive messages related to this topic.</p>
<p><strong>Subscribers:</strong> The entity that consumes and process message.</p>
<p>Publishers send messages to a central hub (topic), without any knowledge of who will receive the message. Any services interested in this publisher will subscribe to the topic where publisher publishes message. Subscribers express interest in one or more topics and receive messages related to those topics.</p>
<h2 id="heading-implementation">Implementation</h2>
<p>There are several ways to implement the pub-sub pattern in a distributed system. Popular options include AWS services like SQS and SNS, which are commonly used for decoupling services and handling asynchronous messaging. SNS (Simple Notification Service) broadcasts messages to multiple subscribers, while SQS (Simple Queue Service) queues messages for processing. Another option is Apache Kafka, a distributed streaming platform renowned for its durability and fault tolerance, making it ideal for high-throughput scenarios. Kafka is <a target="_blank" href="https://kafka.apache.org/documentation/#introduction">well-documented</a> and widely used in large-scale data heavy systems. <a target="_blank" href="https://docs.nats.io/nats-concepts/core-nats/pubsub#publish-subscribe">NATS</a> is another lightweight and high-performance messaging system that is well-suited for cloud-native applications. It supports the pub-sub pattern with low latency and minimal overhead, making it an excellent choice for distributed system where fast, reliable messaging is crucial. Azure offers similar solutions, such as <a target="_blank" href="https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview">Azure Service Bus</a> for reliable messaging between services and <a target="_blank" href="https://learn.microsoft.com/en-us/azure/event-grid/overview">Azure Event Grid</a> for event-based pub-sub communication across various Azure services.</p>
<h3 id="heading-implementing-pub-sub-with-websockets">Implementing Pub-sub with websockets</h3>
<p>Here, I will be using SignalR to implement pub-sub pattern. SignalR simplifies real-time communication between the server and clients, allowing you to send messages to multiple connected clients simultaneously. About system:</p>
<ol>
<li><p><code>publisher.api</code> service acts as a publisher, broadcasting weather data to its subscribers.</p>
</li>
<li><p><code>weathersub</code> is a service that consumes the weather data to perform specific processing tasks.</p>
</li>
<li><p><code>weathersub01</code> is another service that also consumes the weather data for its own processing needs.</p>
</li>
</ol>
<p>When i publish a weather message:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724574464945/b96df1d8-7245-4931-a6a1-d9c9ee732689.png" alt class="image--center mx-auto" /></p>
<p>Subscribers receive messages:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724574583312/83c98a2b-fefd-468a-9a75-3b216e0c44e1.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724574641529/141492a8-7373-4a10-8686-bca070d83343.png" alt class="image--center mx-auto" /></p>
<p>Source code: <a target="_blank" href="https://github.com/sushantpt/pub-sub">Github</a></p>
<p>You might notice that <code>weathersub01</code> receives the message twice. This happens because whenever a new subscriber connects, it triggers the <code>publisher.api</code> to send out the weather data to all connected clients. As a result, every time a subscriber connects, weathersub01 and other subscribers receive a copy of the broadcasted message.</p>
<p>Using SignalR to introduce pub-sub in distributed system is very straightforward and fast. It simplifies real-time communication, making it easy to broadcast messages to multiple connected clients simultaneously. SignalR can be effective for certain use cases in a distributed system, but its suitability depends on specific requirements. If your system is just adapting pub-sub, then SignalR is a good choice due to its ease of integration and real-time messaging capabilities. It’s particularly useful for scenarios where real-time updates are needed and message persistence is not critical.</p>
<h3 id="heading-disadvantages-of-implementing-pub-sub-using-signalr">Disadvantages of implementing pub-sub using SignalR</h3>
<p>One disadvantage of using SignalR for pub-sub is the potential for message duplication. When a new connection is established, it can trigger the publisher to resend data, causing multiple copies of the same message to be received by subscribers.</p>
<p>Another drawback is that if a subscriber is offline or unavailable when a message is sent, it will miss that message entirely. Unlike some other pub-sub systems that provide message persistence or retry mechanisms, SignalR doesn’t inherently store messages for offline subscribers, so any missed messages are not retried or delivered once the subscriber reconnects.</p>
<h3 id="heading-handling-disadvantages">Handling disadvantages</h3>
<p>To handle this, you can add retry mechanism and idempotency to every messages. This approach involves ensuring that every message is processed only once, even if it is received multiple times, and implementing strategies to retry messages if a subscriber is temporarily offline. However, implementing these solutions from scratch can be complex and time-consuming.</p>
<p>Instead of reinventing the wheel, it’s often more practical to use existing tools and systems designed to handle these challenges efficiently. For larger or more complex distributed systems where message durability, high throughput, and guaranteed delivery are crucial, specialized tools like Apache Kafka, NATS, AWS SQS and SNS, or Azure Service Bus and many more such tools might be more appropriate. These tools offer robust solutions for handling large volumes of messages, ensuring message delivery (retry mechanism), and providing fault tolerance.</p>
<h2 id="heading-summary">Summary</h2>
<p>This article explored the pub-sub (publish-subscribe) pattern, which allows a publisher to send messages to multiple subscribers without needing to know who they are. I explained various tools for implementing pub-sub, such as AWS SNS for broadcasting messages, Apache Kafka for durable, high-throughput streaming, NATS for lightweight, high-performance messaging, and Azure services like Service Bus and Event Grid for reliable messaging and event-based communication.</p>
<p>In the implementation part, i used SignalR to implement pub-sub with WebSockets, where <code>publisher.api</code> broadcasts weather data to multiple services like <code>weathersub</code> and <code>weathersub01</code>. A noted disadvantage of SignalR is the potential for message duplication and the risk of missed messages if a subscriber is offline. To address these issues, you could implement custom retry mechanisms and idempotency to handle duplicates and missed messages. However, using specialized tools and systems that already handle these challenges efficiently is often more practical and less complex.</p>
<h2 id="heading-references">References</h2>
<ol>
<li><p><a target="_blank" href="https://aws.amazon.com/what-is/pub-sub-messaging/">Aws article on pub-sub</a></p>
</li>
<li><p><a target="_blank" href="https://natsbyexample.com/examples/messaging/pub-sub/cli">NATS example</a></p>
</li>
<li><p><a target="_blank" href="https://kafka.apache.org/documentation/#introduction">Kafka docs</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=IDJv0S9yf7Q&amp;t=691s">Getting started with Pub-sub by Nick Chapsas</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=rL8ckLV_oRQ">Real-time applications with Azure Web PubSub - Poornima Nayar - NDC Oslo 2023</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Messaging & Queuing technologies]]></title><description><![CDATA[In my previous article, I explained distributed system and communication between them. In this article, I will cover an asynchronous way to establish communication between services through a method known as messaging using some queuing technologies.
...]]></description><link>https://sushantpant.com.np/messaging-queuing-technologies</link><guid isPermaLink="true">https://sushantpant.com.np/messaging-queuing-technologies</guid><category><![CDATA[messaging]]></category><category><![CDATA[message bus]]></category><category><![CDATA[rabbitmq]]></category><category><![CDATA[Asynchronous Communication ]]></category><category><![CDATA[message queue]]></category><category><![CDATA[MassTransit]]></category><category><![CDATA[amqp]]></category><category><![CDATA[distributed system]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Tue, 20 Aug 2024 03:15:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723307788914/8ccfd803-ff04-4356-af8f-40a3e8d096df.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my previous article, I explained distributed system and communication between them. In this article, I will cover an asynchronous way to establish communication between services through a method known as messaging using some queuing technologies.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>Messaging in a broader way is a form of communication between some parties. In distributed system, it refers to the process of sending and receiving messages(data) between some services to provide communication.</p>
<h3 id="heading-asynchronous-messaging">Asynchronous Messaging</h3>
<p>Asynchronous messaging in distributed system is a pattern where sender and the receiver of a message do not need to communicate directly with each other. The sender sends the message but do not wait for the receiver's response. The sender just continues with its operation without waiting for the receiver's response.</p>
<p>For example, if Service A is a sender and Service B is a receiver, in asynchronous messaging, Service A sends a message to an intermediary system (like a message queue), and Service B retrieves and processes the message from that intermediary. Even though Service A and Service B do not interact directly, the message is still delivered and handled through this intermediary system. Using queuing technologies for messaging in a distributed system effectively manages this asynchronous communication.</p>
<h3 id="heading-queuing-technologies">Queuing technologies</h3>
<p>Queuing technologies are just some set of tools and patterns designed to facilitate asynchronous messaging through message queues and message buses. A message queue serves as an intermediary storage system, holding messages until they are processed. Let’s first explore the message queue and then the message bus, while they share similarities, the message bus offers additional features. There are three general components in a queuing system:</p>
<ol>
<li><p>Producer: Who produces message.</p>
</li>
<li><p>Consumer: Who consumes message.</p>
</li>
<li><p>Queue: Place where messages are stored from producer. It store the messages somewhere on the disk until consumer consumes it.</p>
</li>
</ol>
<p>It can be visualized as:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723901775665/160114bb-8db0-4df2-88c3-4e5361b7ef34.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-does-a-message-queue-works">How does a message queue works?</h2>
<p>You might have used socials platform like Facebook or Instagram, where user can configure a settings to receive notifications via in-app push notification, email, or SMS when certain events occur such as receiving a comment on your post.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723564590074/cba7a8f2-74e6-472e-924e-cd7814aaf7dc.png" alt class="image--center mx-auto" /></p>
<p>I'm not sure how Facebook have designed it but if I had to design this feature using queuing technology, I would do so: when a user receives a new comment notification, that notification service creates a message (data) and place that in a message queue. Instead of directly sending notifications through email and SMS services in synchronous way, these services would consume messages from the queue. Each service, such as the email service or SMS service, would pull messages from the queue and process them according to its delivery method. This setup decouples the notification generation from the delivery process, allowing for more flexibility and scalability.</p>
<p>So, message queue operates as a middleware between services. There is a message publisher who sends message, a queue where message is stored until they are processed or queue is full, the consumer who consumes and uses the message accordingly.</p>
<h3 id="heading-what-problem-does-message-queue-solves">What problem does Message queue solves?</h3>
<p>In previous article, I mentioned a lot of What ifs in synchronous communication like: when calling to some remote service and it is unresponsive, scalability issues where we might increase afferent and efferent coupling between services, etc. These things tend to severely impact overall system's performance and reliability. Message queue addresses these challenges and provides a robust and reliable asynchronous mechanism.</p>
<ol>
<li><p><strong>Reliability &amp; Inconsistent data</strong>: When Service A directly calls Service B and Service B becomes unresponsive, it can lead to failures in both services. This issue is compounded when multiple services are involved; for instance, in a system with 20 or more services, a single unresponsive service can disrupt the entire process and result in inconsistent data.</p>
<p> <strong>Solution:</strong> Messaging pattern. Instead of directly calling services, we can rely on some sorta buffer i.e. a message queue. The message will be stored in a queue in a physical queue, until it is processed by some consumer. This buffering mechanism ensures that even if a service is temporarily unavailable, messages are preserved and processed once the service is back online, thereby enhancing reliability and consistency across the system.</p>
</li>
<li><p><strong>Reduced in coupling</strong>: Message queuing decouples the calling (consumer) and the responder (publisher) service. The consumer processes messages from the queue asynchronously, allowing the services to operate independently of each other. This decoupling improves system flexibility and scalability, as changes to one service (such as updates or failures) have minimal impact on the other.</p>
</li>
<li><p><strong>Improved fault tolerance:</strong> Message queues enhance fault tolerance by cutting-off failures. If a service encounters issues, messages remain in the queue and can be processed later once the service recovers. Additionally, message queues often include features like retry mechanisms and dead-letter queues to handle persistent issues, ensuring that the system remains robust and messages are eventually processed.</p>
</li>
<li><p><strong>Proper error handling (using dead letter queue or poison queue):</strong> Most of the message queuing technologies support dead letter queue or poison queue. Imagine a scenario where a publisher sends a message that is faulty or causes an error during processing. Instead of having the system fail or lose the message, it is redirected to a dead letter queue. This queue is specifically designed to capture messages that cannot be processed successfully after several attempts.</p>
</li>
</ol>
<h2 id="heading-types-of-message-queue">Types of Message Queue</h2>
<p>There are various types of message queue. Here are some common ones:</p>
<ol>
<li><p><strong>Point-to-point queue</strong>: In a point-to-point queue system, a producer sends a message to a specific queue intended for a single consumer. Once the message is received by the consumer, it processes the message and sends a response back to the producer. If the response indicates success, the message is removed from the queue, confirming that it has been successfully delivered and processed by the consumer. This mechanism ensures that each message is handled by only one consumer, providing reliable message delivery and acknowledgment.</p>
</li>
<li><p><strong>Publish-subscribe queue</strong>: Here, queue are called "topic". Publisher publishes message to this topic and any number of subscribers subscribed to this topic receives a copy of message. This process is called fanout. Pub-sub queue is ideal when you need to send message to multiple services.</p>
</li>
<li><p><strong>In-memory queue:</strong> Here, queue stores messages on memory rather than on disk or "database". They are performant but not ideal if you want your data to be persisted and durable.</p>
</li>
<li><p><strong>Priority queue</strong>: Typically, a message queue operates on a FIFO (first-in, first-out) basis, meaning messages are processed in the order they are received. However, a priority queue allows messages to be stored and processed according to their priority level. In a priority queue, messages with higher priority are dequeued and processed before those with lower priority, regardless of the order in which they were added. This ensures that critical messages are handled quickly, enhancing the responsiveness of the system to high-priority tasks.</p>
</li>
</ol>
<h2 id="heading-messaging-protocols">Messaging Protocols</h2>
<p>Every queuing technology follow a set of rules on how messages are serialized or formatted, how they communicate, and how they are transmitted. Messaging protocols ensures to enable standard among queuing technology. Here are some commonly used messaging protocols:</p>
<ol>
<li><p><strong>AMQP (Advanced Message Queuing Protocol):</strong> AMQP is a widely used robust, language-agnostic, wire-level messaging protocol that facilitates message oriented middleware. Wire-level means it specifies exactly how data should be structured and transmitted over the network. This allows different services to understand each other, no matter what language or platform they are using. This makes AMQP reliable and useful for complex systems that need to exchange messages consistently and securely.</p>
</li>
<li><p><strong>MQTT (Message Queuing Telemetry Transport):</strong> MQTT is a light weight pub-sub messaging protocol designed for simple and efficient communication, especially over networks that are unreliable. It’s often used in situations where devices have limited processing power or bandwidth, like in IoT applications. MQTT works using a pub-sub pattern, where devices can send messages (publish) to a central broker, and other devices can receive (subscribe to) those messages if they’re interested. This makes it easy to send data from sensors, for example, to a server or other devices, without needing a direct connection between them.</p>
</li>
<li><p><strong>STOMP (Simple Text Oriented Messaging Protocol):</strong> STOMP is a straightforward messaging protocol that's is easy to understand and work with because it is text-based messages. In other word, they are human readable, making it simple to debug and develop with. STOMP is often used to send messages between different services, like sending updates from a server to a web application. It works by having clients connect to a message broker, where they can send (publish) messages or receive (subscribe to) messages. The text-based nature of STOMP makes it accessible and flexible, allowing it to be used in a variety of applications where simplicity and ease of integration are important.</p>
</li>
<li><p><strong>XMPP (Extensible Messaging Presence Protocol):</strong> Mainly used for real-time communication, XMPP is a protocol based on XML. XMPP is extensible, meaning you can add custom features to it, like file sharing or voice calls. This flexibility makes it easy to build more complex applications on top of the basic messaging functions. For example, a simple chat app using XMPP can be extended to include video calls, group chats, or even real-time collaboration tools, all while using the same underlying protocol. XMPP supports real-time updates, so you can see if someone is online, away, or busy. This protocol is widely used in chat applications, collaboration tools, and even IoTs, where quick, real-time communication is important.</p>
</li>
</ol>
<h2 id="heading-understanding-some-popular-queuing-choices">Understanding some popular queuing choices</h2>
<p>There are many popular message queuing technologies out there with its own features and tradeoffs. Here are some popular choices:</p>
<ol>
<li><p><strong>RabbitMQ</strong>: Opensource queuing technology that supports various types of messaging protocols including: AMQP, STOMP, MQTT, HTTP, Web-sockets, etc. It is known for its robustness, and flexibility. RabbitMQ comes with visual interface where you can see and manage queues and exchanges. It is ideal for systems where there are complex routing patterns (meaning there are many rules for deciding where messages should go based on their content), requires data and delivery reliability, and systems using multiple messaging protocols.</p>
</li>
<li><p><strong>AWS Simple Queue Service (SQS):</strong> A fully managed cloud-based queuing system provided by Amazon Web Services (AWS). Fully managed means AWS takes care of servers and infrastructures. SQS are very scalable. There are two types of queues provided by SQS:</p>
<ol>
<li><p>Standard Queue =&gt; High throughput and at-least one delivery but doesn't guarantee the order of messages.</p>
</li>
<li><p>FIFO Queue =&gt; Messages are processed in order they were sent and only once.</p>
</li>
</ol>
</li>
</ol>
<p>    SQS provides options for encrypting messages and controlling access to the queue making it secure and ensuring that only authorized users and services can access or manage the messages. SQS is very ideal for serverless systems.</p>
<ol start="3">
<li><strong>Apache ActiveMQ:</strong> Apache ActiveMQ, an open-source message broker that facilitates communication between different systems or components by handling messages supports various messaging protocols like: AMQP, STOMP, and MQTT, making it versatile. Apache ActiveMQ is ideal for JVM applications where versatility, and reliability are must.</li>
</ol>
<h2 id="heading-message-bus">Message Bus</h2>
<p>A message bus is a more complete messaging framework that serve as a centralized channel for communication between various services in a system. A message bus typically includes all the core features of a message queue, such as reliable message delivery and message storage, and adds additional functionalities for routing, processing, and transforming messages. Like a message queue, it stores messages until they are processed. Additional features like:</p>
<ol>
<li><p><strong>Advanced routing:</strong> The message bus can direct messages to different services based on their content or other factors. For example, it might send customer orders to an order processing service and customer feedback to a support team.</p>
</li>
<li><p><strong>Message processing:</strong> It can handle and modify messages before sending them out. For example, it might add extra information to a message or filter out unnecessary details.</p>
</li>
<li><p><strong>Message Transformation:</strong> The message bus can change messages into different formats or structures to fit the needs of different systems. For example, it might convert a message from XML to JSON.</p>
</li>
<li><p><strong>Pub-Sub Pattern:</strong> Instead of sending messages to one specific place, a message bus can send the same message to multiple destinations. For example, a news update could be sent to both a website and a mobile app (both different services).</p>
</li>
<li><p><strong>Orchestration:</strong> The message bus manages how messages flow between different services. It ensures that the right messages go to the right places in the correct order. For example, it might ensure that a customer’s order goes through several steps, like payment, shipping, and confirmation (in order).</p>
</li>
</ol>
<h3 id="heading-how-does-a-message-bus-works">How does a Message bus works?</h3>
<p>Message bus can be described as message queue on roids. While a message queue focuses on storing and delivering messages in a straightforward, point-to-point manner, a message bus takes it up a notch with additional features (mentioned above). Message infrastructure can be a bit complex to understand, but here is a detail look at it:</p>
<ol>
<li><p><strong>Producer:</strong> A service that generate messages. They send data or events to the message bus. For example, a service might generate a message when a user submits a form.</p>
</li>
<li><p><strong>Consumer:</strong> These are the services that receive and process messages. Consumers subscribe to the message bus to get the messages they are interested in.</p>
</li>
<li><p><strong>Message Broker:</strong> A component within the message bus that routes messages from producers to the appropriate consumers. It may handle tasks like message transformation, and routing based on various criteria.</p>
</li>
<li><p><strong>Message Topics or Channels:</strong> These are logical channels or categories through which messages are classified. Producers and consumers can publish or subscribe to specific topics to filter the messages they handle.</p>
</li>
<li><p><strong>Message Store:</strong> A persistent storage (physical disk) that keeps messages until they are successfully processed. This ensures that messages are not lost in case of failures.</p>
</li>
</ol>
<p>To sum up, a producer generates a message and sends it to the message bus, specifying the intended topic or channel. The message bus, often through its broker, routes the message to the appropriate queue(s) based on the topic or channel specified. The routing may involve applying filters or transformations. The message is temporarily stored in a queue if it cannot be immediately delivered. This ensures that messages are not lost and can be processed later. Consumers subscribe to topics or channels and receive messages from the message bus. The delivery may be direct or involve additional processing based on the bus’s configuration. After processing, the consumer acknowledges receipt of the message. If the processing fails, the message bus might retry delivery or move the message to a dead-letter queue/poison queue for further investigation.</p>
<h3 id="heading-difference-between-message-queue-and-message-bus">Difference between Message queue and Message bus</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Message Queue</td><td>Message Bus</td></tr>
</thead>
<tbody>
<tr>
<td>Stores messages from a producer until they are processed by a consumer.</td><td>Acts as a centralized hub for sending and receiving messages, supporting advanced routing and processing.</td></tr>
<tr>
<td>Easy to understand and implement.</td><td>A bit complex to set up and implement.</td></tr>
<tr>
<td>Best for straightforward, reliable message delivery between specific producer and consumer pairs.</td><td>Best for complex systems needing flexible routing, integration, and support for multiple communication patterns.</td></tr>
</tbody>
</table>
</div><h3 id="heading-what-problem-does-a-message-bus-solves">What problem does a Message bus solves?</h3>
<p>Similar to a message queue, a message bus solves problems related to complex communication patterns, scalability, and system integration. It enhances reliability and fault tolerance by managing message routing, integration across diverse systems, and providing robust monitoring tools. By decoupling services and supporting advanced features like message persistence and transformation, a message bus ensures smooth and scalable communication in complex, distributed environments.</p>
<h2 id="heading-so-message-queue-or-message-bus">So Message queue or Message bus?</h2>
<p>Well, choosing any type of solution really depends upon the requirements.</p>
<ol>
<li><p><strong>Message Queue:</strong> Ideal for simpler use cases where you need reliable, asynchronous communication between components. It focuses on storing and delivering messages between producers and consumers (services), handling scenarios where a producer needs to communicate with a specific consumer.</p>
</li>
<li><p><strong>Message Bus:</strong> Suited for more complex scenarios involving multiple services and diverse communication patterns. It offers advanced features like message routing, transformation, and integration, making it effective for managing communication in distributed systems with diverse interactions.</p>
</li>
</ol>
<p>In summary, use a message queue for straight forward asynchronous communication, or opt for a message bus when you need a more comprehensive solution with enhanced routing, integration, and scalability capabilities.</p>
<h2 id="heading-implementation">Implementation</h2>
<p>Now that you’re familiar with messaging and queuing technologies, let’s put them into practice. Consider this scenario: a payment system where a user can send and receive money. When payment is completed, both sender and receiver will receive a promotional email and SMS notification. So there are 3 services, <code>payment.API</code>,<code>promotional.Email</code> and <code>promotional.SMS</code>.</p>
<p>I'll use <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/introduction">.NET 8</a>, <a target="_blank" href="https://www.rabbitmq.com/docs">RabbitMQ</a>, and <a target="_blank" href="https://masstransit.io/introduction">MassTransit</a> to build this system.</p>
<blockquote>
<p>MassTransit is an open-source distributed application framework for .NET that provides a consistent abstraction on top of the supported message transports. The interfaces provided by MassTransit reduce message-based application complexity and allow developers to focus their effort on adding business value.</p>
</blockquote>
<p>Basically, masstransit is a wrapper messaging technologies (most of the messaging frameworks and technologies) providing high level abstraction to use any types of messaging or queuing technologies with added functionalities like sagas, retries, transactional, and more to build resilient and robust distributed system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724050323435/3575c502-55f3-4ef5-a887-5b05919e3a99.png" alt class="image--center mx-auto" /></p>
<p>Here, message publisher is <code>payment.API</code> whereas message receivers are <code>promotional.Email</code> and <code>promotional.SMS</code>.</p>
<p>An exchange is a virtual entity within RabbitMQ that receives messages from producers and routes them to queues based on certain rules. It acts as a central hub for message distribution. There are several types of exchanges in RabbitMQ, but the most common ones are:</p>
<ol>
<li><p><strong>Direct Exchange:</strong> This is the simplest type. Messages are routed to queues based on an exact match between the routing key specified by the producer and the binding key of the queue.</p>
</li>
<li><p><strong>Fanout Exchange:</strong> This exchange broadcasts messages to all queues.</p>
</li>
<li><p><strong>Topic Exchange:</strong> This exchange allows for flexible routing based on patterns in the routing key.</p>
</li>
<li><p><strong>Headers Exchange:</strong> This exchange routes messages based on message headers, not the routing key.</p>
</li>
</ol>
<p>Routing determines how messages are delivered from an exchange to specific queues. Routing Key =&gt; A string set by the producer when publishing a message. It's used to determine the destination queue. Binding Key =&gt; A pattern associated with a queue. It defines which messages the queue will receive.</p>
<p>By default, MassTransit creates an exchange called <code>amq.default</code>.This is a direct exchange, meaning messages are routed based on an exact match with the routing key.</p>
<p>So, wherever sender transfer fund to a receiver, both of them will get an email and SMS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724052496366/c587b4ce-3cf5-49b9-bcc1-0d2f39032a85.png" alt class="image--center mx-auto" /></p>
<p><code>payment.API</code>'s swagger UI.</p>
<ol>
<li>Seed payment accounts. It will generate random users and other information.</li>
</ol>
<ol start="2">
<li><p>View all account.</p>
</li>
<li><p>Copy account no and transfer fund.</p>
</li>
<li><p>You can check both account in GET request.</p>
</li>
</ol>
<p>Payment transferred from payment.API like so:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724052874794/488954b7-6520-4a28-a80e-59575a325285.png" alt class="image--center mx-auto" /></p>
<p>This message will be published and processed by other services.</p>
<p>SMS service:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724052940344/8d10ed7a-4d81-4e09-a32e-0c2755c47f8e.png" alt class="image--center mx-auto" /></p>
<p>Email service:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724053013719/088893e4-4405-4cd8-adac-d1dba78103e4.png" alt class="image--center mx-auto" /></p>
<p>This solution offers fault tolerance and resiliency. If either the SMS or email service experiences downtime, messages will be queued and processed when the service becomes available again.</p>
<p>Full source code: <a target="_blank" href="https://github.com/sushantpt/distributed_system">Github</a></p>
<h2 id="heading-messaging-is-the-solution">Messaging is the solution?</h2>
<p>No. It depends. A fundamental principle in distributed system design is to minimize direct communication between services. However, preferring asynchronous communication over sync introduces a tradeoff: request-response.</p>
<p>The decision to implement messaging should be deliberate and based on a careful evaluation of project requirement and trade-offs.</p>
<h2 id="heading-summary">Summary</h2>
<p>This article explores asynchronous messaging in distributed systems, focusing on how messaging facilitates communication between services without requiring direct interaction and key concepts like message queues and message buses, explaining their roles in decoupling services, improving reliability, and enhancing fault tolerance. Using RabbitMQ, MassTransit, and .NET 8, I demonstrate building a payment system that sends email and SMS notifications highlighting the benefits of asynchronous messaging, exploring concepts like message queues, message buses, and various protocols (AMQP, MQTT, STOMP). I will try to publish more articles on building data consistency over the system, resiliency, and security next.</p>
<h1 id="heading-references"><strong>References</strong></h1>
<p>Messaging: <a target="_blank" href="https://www.youtube.com/watch?v=vnGLiJs089s">NDC presentation by Chris Patterson</a></p>
<p>RabbitMQ: <a target="_blank" href="https://www.rabbitmq.com/docs">docs</a></p>
<p>MassTransit: <a target="_blank" href="https://www.youtube.com/watch?v=4squjqvE8g0&amp;t=619s">Good intro to MassTransit by Milan Jovanović</a>, <a target="_blank" href="https://www.youtube.com/watch?v=4FFYefcx4Bg&amp;t=334s">Nick Chapsas Tutorial</a></p>
<p>More: <a target="_blank" href="https://masstransit.io/documentation/patterns/saga">About Saga Pattern</a>, <a target="_blank" href="https://developer.ibm.com/articles/messaging-protocols/">Messaging Protocols</a>, <a target="_blank" href="https://learn.particular.net/courses/distributed-systems-design-fundamentals-online">Distributed system design fundamental course by Udi Dahan</a>, <a target="_blank" href="https://www.youtube.com/watch?v=5VQz28oABo0">Async communication in Distributed System</a></p>
<p>Diagram: <a target="_blank" href="https://draw.io">draw.io</a></p>
]]></content:encoded></item><item><title><![CDATA[Understanding distributed system]]></title><description><![CDATA[Introduction
2 words "distributed" and "system" meaning a system which is built up of multiple components that work together as-a-whole. For instance, consider an online platform like Amazon. It is made up of various services to handle inventory mana...]]></description><link>https://sushantpant.com.np/understanding-distributed-system</link><guid isPermaLink="true">https://sushantpant.com.np/understanding-distributed-system</guid><category><![CDATA[distributed system]]></category><category><![CDATA[message queue]]></category><category><![CDATA[event-driven-architecture]]></category><category><![CDATA[PubSub]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[.NET]]></category><category><![CDATA[message broker]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Mon, 19 Aug 2024 09:45:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722337564556/760d6ad8-a0b9-4eea-9a32-df7d63ff876b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>2 words "distributed" and "system" meaning a system which is built up of multiple components that work together as-a-whole. For instance, consider an online platform like Amazon. It is made up of various services to handle inventory management, authentication, order processing, and payments and many more. These services must communicate effectively to ensure that users experience a seamless shopping experience. For example, when a customer places an order, the system needs to update the inventory, process the payment, and prepare the shipment. These components may be separated physically across different networks or located on a same network.</p>
<h3 id="heading-system-separated-physically-vs-local">System separated Physically vs. Local</h3>
<p>Firstly, two aspects to understand: components separated physically and components on the same network.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Physically separated</strong></td><td><strong>On a same network (Local)</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Distributed geographically. Meaning some <code>Service A</code> might be deployed in Europe and some <code>Service B</code> might be deployed in Asia. Despite being physically separated, they form a cohesive unit.</td><td>Distributed locally. Meaning some <code>Service A</code> and <code>Service B</code> might be deployed within the same network, or a data center to form as a cohesive unit.</td></tr>
<tr>
<td>Communication between services occurs over a WAN (wide area network) or over the internet.</td><td>Communication between services occurs over a LAN (local area network), an internal network (intranet), or the internet.</td></tr>
<tr>
<td>High latency in geographically distributed systems is due to longer distances data must travel.</td><td>Lower latency in the same network are due to shorter data travel distances.</td></tr>
<tr>
<td>Data consistency is challenging. Keeping all distributed services synchronized is hard.</td><td>Data consistency is less challenging.</td></tr>
<tr>
<td>Easily scalable. Adding more resources (horizontal scaling) across different locations can handle increased demand, but requires managing network latency and data consistency.</td><td>Is scalable, but adding more resources can cause throughput and bandwidth issues when network becomes congested.</td></tr>
</tbody>
</table>
</div><p>Building a bad distributed system is straightforward, just call an RPC on another service and ignore resiliency, data consistency, fault tolerance, security, and other crucial aspects. However, building a robust, efficient, and reliable distributed system is challenging and complex.</p>
<p>Now its clear about "being distributed", questions like how to establish communication between these components, have data consistency all over the component, handle failures, and many more arises.</p>
<h2 id="heading-communication">Communication</h2>
<p>There are several ways to establish communication between services. Effective communication is fundamental to ensuring that the system operates as a cohesive unit. In general, communication can be categorized into two types: synchronous and asynchronous.</p>
<h3 id="heading-synchronous-communication">Synchronous communication</h3>
<p>In synchronous communication, a service makes a request and waits for a response before proceeding. Also know as the request-response pattern. Basically some <code>service A</code> request to <code>service B</code> and waits for <code>service B</code> to process the request. Example using synchronous communication:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">List</span>&lt;<span class="hljs-title">string</span>&gt; _database</span> = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">string</span>&gt;();
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">CreateNewCustomer</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> customer</span>)</span>
{
    _database.Add(customer);
    <span class="hljs-comment">// also save to service B</span>
    <span class="hljs-keyword">using</span> HttpClient client = <span class="hljs-keyword">new</span> HttpClient();
    HttpResponseMessage response = <span class="hljs-keyword">await</span> client.PostAsync(<span class="hljs-string">"https://api.serviceb.com/v1/welcome/sendEmail"</span>, <span class="hljs-keyword">new</span> StringContent(customer));
    response.EnsureSuccessStatusCode();
    <span class="hljs-keyword">return</span> response.IsSuccessStatusCode;
}
</code></pre>
<p>In this example, Service A first adds the customer to the local <code>_database</code> with <code>_database.Add(customer);</code> and then makes a POST request to Service B to send a welcome email. This is a common practice where, upon a new user's registration, a welcome email is sent to enhance user engagement.</p>
<p>Although this function is <code>async</code>, the interaction between Service A and Service B is synchronous in practice. When <code>await</code> is used to POST request service B, it pauses the execution of the <code>CreateNewCustomer()</code> (but doesn't block thread) until the awaited task completes (more on <a target="_blank" href="https://sushantpant.com.np/async-and-await">async await</a>). During this pause, control returns to the calling method, and the thread is free to perform other operations. This means Service A waits for Service B's response before moving forward. The function does not complete until the response from Service B is received, effectively making the interaction synchronous.</p>
<p><strong>What ifs ...</strong></p>
<ol>
<li><p>Service B is slow or down? Service B might be down for maintenance.</p>
</li>
<li><p>Service B throws an error or Service B throttles due to high number of users registration. Explanation: <em>If a large number of users register, Service A processes the registrations, but when it tries to send welcome emails, Service B might throttle the requests due to high volume. A common approach to manage email sending is through queuing. However, queues have limits and can only handle a certain number of requests at a time. If the queue is full, additional requests may be delayed or rejected, leading to throttling issues.</em></p>
</li>
<li><p>After sending welcome email i would also like to include them in some sort of marketing camp. Adding another call to Service C?</p>
<ol>
<li>What if Service A (creating customer), and Service B(sending welcome email) succeed but service C (marketing camp) failed?</li>
</ol>
</li>
</ol>
<h3 id="heading-asynchronous-communication">Asynchronous communication</h3>
<p>In asynchronous communication, a service makes a request but doesn't wait for the response. It just moves forward. Basically some Service A requests Service B without waiting for Service B response.</p>
<p>Some ways to achieve asynchronous communication are:</p>
<h3 id="heading-messaging">Messaging</h3>
<p>Basically sending data in a non-blocking way using some sort of queuing system. A message queue can be defined as a process where messages (data) are stored in a queue and then some other services processes it. Working mechanism: Some Service A sends data (<em>a producer</em>) to a message queue, then some service B processes (<em>a consumer</em>) the queue accordingly. The queue acts as a buffer which holds messages until they are processed by a consumer (or delete after some time). Messaging solves a crucial issue we had in synchronous communication, i.e. what if some n number of services are added to increase user enhancement:</p>
<blockquote>
<ol start="3">
<li>After sending welcome email i would also like to include them in some sort of marketing camp. Adding another call to Service C?</li>
</ol>
</blockquote>
<p>Using a message queue, any number of services can consume the messages from the queue. Queues can further be categorized into topics. Topic helps to categorize messages(data). Messaging can be visualized like so:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722853354277/eedd3746-ed43-49a8-9a71-361ffc0d5562.png" alt="Messaging using queuing" class="image--center mx-auto" /></p>
<p>In summary, messaging with queuing technology provides a robust and resilience way to achieve asynchronous communication.</p>
<h3 id="heading-pub-sub-pattern"><strong>Pub-Sub pattern</strong></h3>
<p>The publish-subscribe (pub-sub) pattern is another asynchronous way to commute between services. Simply understanding pub-sub, a service (publisher) publishes a message and other services (subscribers) interested in that publisher receives that message. This is very similar to YouTube channel where user can subscribe to their favorite creator. User will be notified when their fav creator publish a video.</p>
<p><strong>Publisher:</strong> Service which sends a message to a message broker. Publisher sends message without knowing who will receive them.</p>
<p><strong>Message broker</strong>: Sorta middleman whose job is to distribute message from Service A to Service B or from Service A to multiple services. It ensures messages are delivered to all interested subscribers.</p>
<p><strong>Subscriber</strong>: Service which receives message through a broker.</p>
<p>Pub-sub pattern can be visualized as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723292700067/2fb797ee-161e-4e93-af67-ef120a538a4b.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-pub-sub-using-web-sockets"><strong>Pub-sub using Web sockets</strong></h3>
<p>One way to implement pub/sub pattern between services is to use web sockets. Web socket provides a real time, point to point communication channel in a long lived connection between services. Simply understanding, using web sockets allows a service to send messages to other services instantly and continuously without reconnecting every single time. There are 2 key components in web sockets: publisher and subscriber (same as above). The publisher broadcasts(send) messages to all subscribers connected to the Web Socket, allowing for immediate and continuous communication.</p>
<p>Pub-sub pattern using web socket can be easily implemented in .NET applications using <a target="_blank" href="https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#what-is-signalr">SignalR</a>. (I'll go more into this later). SignalR simplifies working with web socket and provides high level abstraction to jump right into logic without worrying about low-level details.</p>
<p>Pub-sub using web socket can be visualized as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723291771346/8d09bd3a-eab2-4616-b122-67edd9d5b884.png" alt class="image--center mx-auto" /></p>
<p>So basically, Pub-sub using web socket (SignalR) enables direct and close to real-time communication between services (publisher and subscribers).</p>
<h3 id="heading-event-driven-approach"><strong>Event-driven approach</strong></h3>
<p>Event-driven approach (or Event-driven Architecture) (EDA) is an pattern where systems operate based on some events. EDA can be explained using a simple example of vending machine. Lets say you want to get a drink (Coke) from a vending machine:</p>
<ol>
<li><p>You select your choice of drink (i.e. Coke) (<code>ItemSelected</code>)</p>
</li>
<li><p>Then you make a payment using some sort of online payment vendors or cash <code>PaymentCompleted</code></p>
</li>
<li><p>The vending machine verifies the payment (after <code>PaymentCompleted</code> event).</p>
</li>
<li><p>If payment was successful, the vending machine will dispense the drink. (<code>DrinkDispensed</code>)</p>
</li>
</ol>
<p>Each action generates an event. Generated events trigger more events. Events drive the flow of the system.</p>
<p>A key pattern to observe in above bullet points, all events are past tensed. This is because an event represent an action or changes that has already occurred in the system. Event cannot be <code>ItemSelected</code> or <code>CompletePayment</code>, or <code>DispenseADrink</code>, etc.</p>
<p>In EDA, a system is designed to respond to actions that have already occurred and perform subsequent operations based on these actions. The ordering of events is critical, as the sequence of actions determines the flow of the system. Additionally, ensuring transactional integrity is essential to maintain consistency and reliability within the system. System can be "transactional" by using Saga pattern, and event sourcing pattern (More on this later).</p>
<p>If i had to design a software system for vending machine:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723296222917/39a26668-b33c-4fd5-96b6-c20537843e1b.png" alt class="image--center mx-auto" /></p>
<p>Here,</p>
<ul>
<li><p>Event(Service) Bus : Routes events between different services. It ensures events are properly delivered to handle them. This can be a Service Z.</p>
</li>
<li><p>Service A : Can be a frontend where user will select their choice of drink. This will generate <code>ItemSelected</code> event.</p>
</li>
<li><p>Service B : User makes a payment for their choice of drink. This will generate <code>PaymentCompleted</code>event.</p>
</li>
<li><p>Service C : User will receive their choice of drink. This will generate <code>DrinkDispensed</code> event.</p>
</li>
</ul>
<p>That's how a typical EDA can be explained but this is not perfect for real world scenario.</p>
<p><strong>What ifs..</strong></p>
<ul>
<li><p>In Service A, there is no coke (selected drink)?</p>
</li>
<li><p>Payment failed?</p>
</li>
<li><p><code>DrinkDispensed</code> occured before <code>PaymentCompleted</code> or inappropriate ordering of events? (more about Event Sourcing in later articles)</p>
</li>
<li><p>Some services are unresponsive.</p>
</li>
<li><p>Duplicate events. <code>DrinkDispensed</code> occured twice (well, it can be. What if the user paid for 2 drinks? But what about if <code>PaymentCompleted</code> occured twice?).</p>
</li>
<li><p>Loss of a event. User paid for a drink but no response. Why? Services being unresponsive, loss of a event in-between?</p>
</li>
</ul>
<p>In Event-Driven Approach (EDA), it is crucial to conduct thorough requirements gathering to identify all possible actions and events. Implementing robust error handling, ensuring transactional integrity, and incorporating fault tolerance strategies are essential for maintaining system reliability and efficiency in real-world scenarios. These measures ensure that the system can handle unexpected situations, such as errors, service unresponsiveness, and event inconsistencies, effectively.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, I covered the basics of distributed systems, including the differences between geographically and locally distributed systems. Effective communication between services can be synchronous or asynchronous, with methods like messaging and pub-sub patterns enhancing decoupling and resilience. The Event-Driven Approach (EDA) was explored as a method for handling operations based on events, emphasizing the need for thorough event handling, error management, and maintaining transactional integrity. Proper implementation of these concepts is essential for building reliable and efficient distributed systems. Stay tuned for more detailed discussions on each topic.</p>
]]></content:encoded></item><item><title><![CDATA[Pattern Matching, Switch Expression and More]]></title><description><![CDATA[One of the major feature of C# version 7.0 was pattern matching. Pattern matching is a way to recognize structure or pattern within some context. Think of pattern matching like a simple puzzle where you examine the pieces and look for matching edges ...]]></description><link>https://sushantpant.com.np/pattern-matching-switch-expression-and-more</link><guid isPermaLink="true">https://sushantpant.com.np/pattern-matching-switch-expression-and-more</guid><category><![CDATA[pattern-matching]]></category><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Fri, 22 Mar 2024 17:09:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711126720594/0a81a050-a04c-4432-a026-8bbbdd923e1f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the major feature of C# version 7.0 was pattern matching. Pattern matching is a way to recognize structure or pattern within some context. Think of pattern matching like a simple puzzle where you examine the pieces and look for matching edges or specific shapes that fit together. Similarly, in C# pattern matching is looking at the data or context and look for patterns that match the criteria.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>Categorizing and processing data based on some context is called pattern matching. By context I mean specific characteristics, properties, or structure of the data that we are analyzing. This context provides the criteria or patterns against which we match and classify the data, allowing us to make informed decisions and take appropriate actions. Pattern matching can help make codebase look much more concise. In this article, I will introduced you to various types of pattern matching.</p>
<h2 id="heading-basic-patterns">Basic Patterns</h2>
<p>Basic pattern are simple building blocks of pattern matching which is used to compare an expression's value against simple criteria.</p>
<p>Here are some basic pattern:</p>
<h3 id="heading-constant-pattern">Constant pattern</h3>
<p>It allows you to match a specific constant value against the value being evaluated. Constant pattern makes conditional logic concise and introduce better readability.</p>
<p>Eg: Using <code>is</code> operator.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> message = <span class="hljs-string">"Welcome back!"</span>;
<span class="hljs-keyword">if</span>(message <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>){
   Console.WriteLine(<span class="hljs-string">"Message is null"</span>);
}
<span class="hljs-comment">// Output: Since, condition is not fullfiled, it won't print message.</span>
</code></pre>
<p>You can use <code>is</code> operator to check for specific match. C# version 9.0 introduced <code>not</code> operator. Now, you check of specific match like:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> message = <span class="hljs-string">"Welcome back!"</span>;
<span class="hljs-keyword">if</span> (message <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>){
   Console.Writeline(<span class="hljs-string">$"Message is not null. <span class="hljs-subst">{message}</span>"</span>);
}
<span class="hljs-comment">// Output: Message is not null. Welcome back!</span>
</code></pre>
<p>Constant patterns can be used with various other expressions like variables, literals, properties, method calls, and more.</p>
<h3 id="heading-relational-pattern"><strong>Relational Pattern</strong></h3>
<p>Similar to constant pattern which checks for a constant specific value, relational pattern checks for a constant specific value and apply relational operators. Imaging if you want to write a logic which checks if the message is not null and message's length is greater than 20.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> message = <span class="hljs-string">"Welcome back!"</span>; <span class="hljs-comment">// length = 13</span>
<span class="hljs-keyword">if</span>(message <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; message.Length <span class="hljs-keyword">is</span> not &lt; <span class="hljs-number">20</span>)
    Console.WriteLine(message);
<span class="hljs-keyword">else</span> Console.WriteLine(<span class="hljs-string">"Welcome back to FC 24!"</span>);
<span class="hljs-comment">// output: Welcome back to FC 24!</span>
</code></pre>
<p>Relational pattern is same as constant pattern but you can use relational operators.</p>
<h3 id="heading-type-pattern"><strong>Type Pattern</strong></h3>
<p>As the name says, type pattern checks if the value is of some specific type. Imagine a scenario where you have an object which may be of type <code>string</code> or <code>int</code>. If it is <code>string</code>, its a name else its an age. You can perform this conditional logic by:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">isNameOrAge</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> data</span>)</span>
{
    <span class="hljs-keyword">if</span> (data <span class="hljs-keyword">is</span> <span class="hljs-keyword">string</span> name)
        Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{name}</span> is a name."</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (data <span class="hljs-keyword">is</span> <span class="hljs-keyword">int</span> age)
        Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{age}</span> ia an age."</span>);
    <span class="hljs-keyword">else</span> Console.WriteLine(<span class="hljs-string">"Invalid"</span>);
}
isNameOrAge(<span class="hljs-string">"ram bahadur"</span>); <span class="hljs-comment">// prints: ram bahadur is a name.</span>
isNameOrAge(<span class="hljs-number">21</span>); <span class="hljs-comment">// prints: 21 ia an age.</span>
</code></pre>
<p>You can read this: <code>if (data is string name) ...</code> like if <code>data</code>'s type is <code>string</code>, assign that value to <code>name</code>, <code>else if (data is int age) ...</code> else if it is <code>int</code>, assign that value to <code>age</code>.</p>
<h3 id="heading-declaration-pattern"><strong>Declaration Pattern</strong></h3>
<p>This is similar to type pattern but declares a new value if an condition is fulfilled. Imagine a scenario where you need to write a logic to check if a person's age is greater than 21. But age can be of type <code>string</code> or <code>int</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">isGreaterThan21</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> age</span>)</span>
{
    <span class="hljs-keyword">if</span> (age <span class="hljs-keyword">is</span> <span class="hljs-keyword">int</span> ageIntValue || (age <span class="hljs-keyword">is</span> <span class="hljs-keyword">string</span> ageStringValue &amp;&amp; <span class="hljs-keyword">int</span>.TryParse(ageStringValue, <span class="hljs-keyword">out</span> ageIntValue) &amp;&amp; ageIntValue <span class="hljs-keyword">is</span> &lt; <span class="hljs-number">21</span>))
        Console.WriteLine(<span class="hljs-string">$"Age is <span class="hljs-subst">{ageIntValue}</span>. You cannot play this game."</span>); 
    <span class="hljs-keyword">else</span>
        Console.WriteLine(<span class="hljs-string">$"You can play this game."</span>);
}
isGreaterThan21(<span class="hljs-string">"42"</span>);
isGreaterThan21(<span class="hljs-number">15</span>);
<span class="hljs-comment">/*
Output: 
       You can play this game.
       Age is 15. You cannot play this game.
*/</span>
</code></pre>
<p>Let me break down this code: <code>if (age is int ageIntValue || (age is string ageStringValue &amp;&amp; int.TryParse(ageStringValue, out ageIntValue) &amp;&amp; ageIntValue is &lt; 21))</code></p>
<p>In my first <code>or</code> condition, I checked if age is <code>int</code>. If it is <code>int</code> then, create a new variable of type <code>int</code> called <code>ageIntValue</code> and assign <code>object age</code>'s value to it. It won't check for another condition. After that it will move on to another line which prints out some message.</p>
<p>If my first <code>or</code> condition fails, it will check second condition. In second condition, I've checked if it is <code>string</code>. If it is an <code>string</code>, then create a new variable of type <code>string</code> called <code>ageStringValue</code> and assign <code>object age</code> value to it. After that I have an <code>and</code> operator which parse <code>ageStringValue</code> into <code>int</code> and assign it to <code>ageIntValue</code>. Finally, another <code>and</code> operator which checks if <code>ageIntValue</code> is greater than 21 (using relational pattern).</p>
<h2 id="heading-switch-expression">Switch Expression</h2>
<p>Switch expression were introduced in C# version 8.0 to write more concise switch "statement". Instead of chaining <code>if() else()</code>, switch statement is much more versatile and concise.</p>
<p>Switch expression is a evolution of switch statements with added benefit of chaining pattern matching.</p>
<p>Here is simple switch statement which prints about fruit:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">GetFruitInfo_SwitchStatement</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> fruitName</span>)</span>
{
    <span class="hljs-keyword">switch</span> (fruitName.ToLower())
    {
        <span class="hljs-keyword">case</span> <span class="hljs-string">"apple"</span>:
            Console.WriteLine(<span class="hljs-string">"An apple a day keeps the doctor away!"</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"banana"</span>:
            Console.WriteLine(<span class="hljs-string">"Banana is good for potassium."</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"orange"</span>:
            Console.WriteLine(<span class="hljs-string">"Oranges are a great source of Vitamin C."</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"mango"</span>:
            Console.WriteLine(<span class="hljs-string">"Mangoes are delicious and refreshing."</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"grapes"</span>:
            Console.WriteLine(<span class="hljs-string">"Grapes come in many varieties, red, green, and purple!"</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"strawberry"</span>:
            Console.WriteLine(<span class="hljs-string">"Strawberries are perfect for adding a sweet touch to desserts."</span>);
            <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">default</span>:
            Console.WriteLine(<span class="hljs-string">"Not a fruit."</span>);
            <span class="hljs-keyword">break</span>;
    }
}
<span class="hljs-comment">// calling code</span>
GetFruitInfo_SwitchStatement(<span class="hljs-string">"grapes"</span>);
<span class="hljs-comment">/*
Output: Grapes come in many varieties, red, green, and purple!
*/</span>
</code></pre>
<p>Now, I will change the same switch statement to switch expression:. Before that I would like to let you know that <code>void</code> is not supported for switch expression. You can return <a target="_blank" href="https://sushantpant.com.np/delegates-in-csharp"><code>Action</code></a> for similar (<code>void</code>) result.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> <span class="hljs-title">GetFruitInfo_SwitchExpression</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> fruitName</span>)</span> =&gt; fruitName.ToLower() <span class="hljs-keyword">switch</span>
{
    <span class="hljs-string">"apple"</span> =&gt; <span class="hljs-string">"An apple a day keeps the doctor away!"</span>,
    <span class="hljs-string">"banana"</span> =&gt; <span class="hljs-string">"Banana is good for potassium."</span>,
    <span class="hljs-string">"orange"</span> =&gt; <span class="hljs-string">"Oranges are a great source of Vitamin C."</span>,
    <span class="hljs-string">"mango"</span> =&gt; <span class="hljs-string">"Mangoes are delicious and refreshing."</span>,
    <span class="hljs-string">"grapes"</span> =&gt; <span class="hljs-string">"Grapes come in many varieties, red, green, and purple!"</span>,
    <span class="hljs-string">"strawberry"</span> =&gt; <span class="hljs-string">"Strawberries are perfect for adding a sweet touch to desserts."</span>,
    _ =&gt; <span class="hljs-string">"Not a fruit."</span>
};
<span class="hljs-comment">// calling code</span>
Console.WriteLine(GetFruitInfo_SwitchExpression(<span class="hljs-string">"strawberry"</span>)); 
<span class="hljs-comment">/*
Output: Strawberries are perfect for adding a sweet touch to desserts.
*/</span>
</code></pre>
<p>This is much more concise. But conciseness isn't the only advantage of switch expressions. It's the combination of switch expressions with pattern matching that makes them truly versatile and powerful. To demonstrate this, lets modify our parameter <code>fruitName</code> from <code>string</code> to an <code>object</code> type. I will create an immutable data which consist detail of the fruit.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">Fruit</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> name, <span class="hljs-keyword">decimal</span> cost, <span class="hljs-keyword">string</span> producedCountry</span>)</span>;
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> <span class="hljs-title">GetFruitInfo_SwitchExpression</span>(<span class="hljs-params">Fruit fruit</span>)</span> =&gt; fruit <span class="hljs-keyword">switch</span>
{
    { name: <span class="hljs-string">"apple"</span>, costInUSD: &lt; <span class="hljs-number">0.5</span>m, producedIn: <span class="hljs-string">"Nepal"</span>} =&gt; <span class="hljs-string">"An apple from Nepal which is cost efficient."</span>,
    { name: <span class="hljs-string">"apple"</span>, costInUSD: &gt; <span class="hljs-number">2</span>, producedIn: not <span class="hljs-string">"Nepal"</span>} =&gt; <span class="hljs-string">"An apple which is not from Nepal and is expensive."</span>,
    { name: <span class="hljs-string">"apple"</span>, costInUSD: &lt; <span class="hljs-number">1</span>,  producedIn: _ } =&gt; <span class="hljs-string">"A juicy apple."</span>,
    { name: <span class="hljs-string">"apple"</span>, costInUSD: _ , producedIn: _ } =&gt; <span class="hljs-string">"An apple."</span>,
    _ =&gt; <span class="hljs-string">"Not an apple."</span>
};
<span class="hljs-comment">// calling code</span>
Fruit fruit = <span class="hljs-keyword">new</span> Fruit(name: <span class="hljs-string">"apple"</span>, costInUSD: <span class="hljs-number">0.75</span>m, producedIn: <span class="hljs-string">"Nepal"</span>);
Fruit fruit1 = <span class="hljs-keyword">new</span> Fruit(name: <span class="hljs-string">"apple"</span>, costInUSD: <span class="hljs-number">4.5</span>m, <span class="hljs-literal">null</span>);

Console.WriteLine(GetFruitInfo_SwitchExpression(fruit)); 
Console.WriteLine(GetFruitInfo_SwitchExpression(fruit1)); 
<span class="hljs-comment">/*
Output:  A juicy apple.
         An apple which is not from Nepal and is expensive.
*/</span>
</code></pre>
<p>This switch expression leverages pattern matching (Constant Pattern using <code>not</code>, and Relational Pattern using <code>&lt; &gt;</code> ) to compare the properties of the <code>fruit</code> object against different cases. Each case is enclosed in curly braces <code>{}</code>.</p>
<p>Each case in the expression doesn't explicitly use a <code>return</code> statement. This is because of lambda. You can find more about lambda and closed variables <a target="_blank" href="https://sushantpant.com.np/captured-variables-lambda-expression-and-closures">here</a>. Basically result of this lambda function is the return type/value of <code>GetFruitInfo_SwitchExpression()</code> function. <code>_</code> is known as discard. I will explain this next, for now think this as <code>default</code> of switch statement.</p>
<h3 id="heading-discard-pattern">Discard Pattern</h3>
<p>Discard is denoted by <code>_</code> (underscore). Discard pattern is used when you don't want a value or you don't care about something. Discard pattern automatically infer type, meaning <code>_</code>'s type will be automatically inferred based on the context(value assigned to it). Discarded value will also not be stored in a allocated memory, but stored in a temporary variable which will be collected by garbage collector.</p>
<p>Examples:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> someVal = <span class="hljs-string">"44"</span>;
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">int</span>.TryParse(someVal, <span class="hljs-keyword">out</span> _ )) <span class="hljs-comment">// discard pattern</span>
    Console.WriteLine(<span class="hljs-string">"someVal is a int."</span>);
<span class="hljs-comment">// output: someVal is a int.</span>

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> <span class="hljs-title">GetFruitInfo_SwitchExpression</span>(<span class="hljs-params">Fruit fruit</span>)</span> =&gt; fruit <span class="hljs-keyword">switch</span>
{
    { name: <span class="hljs-string">"apple"</span>, costInUSD: &lt; <span class="hljs-number">0.5</span>m, producedIn: <span class="hljs-string">"Nepal"</span>} =&gt; <span class="hljs-string">"An apple from Nepal which is cost efficient."</span>,
    { name: <span class="hljs-string">"apple"</span>, costInUSD: &gt; <span class="hljs-number">2</span>, producedIn: not <span class="hljs-string">"Nepal"</span>} =&gt; <span class="hljs-string">"An apple which is not from Nepal and is expensive."</span>,
    _ =&gt; <span class="hljs-string">"Not an apple."</span> <span class="hljs-comment">// any Fruit except apple will reach here.</span>
};
GetFruitInfo_SwitchExpression(<span class="hljs-string">"orange"</span>);
<span class="hljs-comment">// output: Not an apple.</span>
</code></pre>
<h2 id="heading-deconstruction-patterns">Deconstruction Patterns</h2>
<p>Deconstruction pattern are simply deconstructing an object(extracting information) and applying your conditional logic. Before moving on to some deconstruction pattern, let's look at deconstruct in C#.</p>
<h3 id="heading-deconstruct">Deconstruct</h3>
<p>Deconstructing was introduced in C# version 7.0. Main motive of deconstruct is to pull out data from an user defined type.</p>
<p>Deconstructing is done by adding a method of type void with name <code>Deconstruct</code>. This method's parameter are those which you want the user of this object to pull out. <code>Deconstruct</code> method takes only out parameter. Why? Because <code>Deconstruct</code> method needs to return back value to the caller which is not done by <code>return</code> statement but <code>out</code> parameter. Why? <code>Deconstruct</code> method extract values outside the method. So when you pass a parameter to <code>Deconstruct</code>, the method assigns the extracted values directly to those parameter.</p>
<p>Here's a simple example:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">struct</span> <span class="hljs-title">LaptopRecommendation</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> _budget, <span class="hljs-keyword">string</span> _brand</span>)</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> budget = _budget;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> brand = _brand;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deconstruct</span>(<span class="hljs-params"><span class="hljs-keyword">out</span> <span class="hljs-keyword">decimal</span> LaptopBudget, <span class="hljs-keyword">out</span> <span class="hljs-keyword">string</span> LaptopBrand</span>)</span> =&gt; (LaptopBudget, LaptopBrand) = (budget, brand);
}
</code></pre>
<p>Now, when any caller use <code>LaptopRecommendation</code> object, they can leverage <code>Deconstruct</code> method. Basically the caller can easily unpack <code>LaptopRecommendation</code> object's property (<code>budget</code> and <code>brand</code>) into a separate variables so, the caller can efficiently interact with the <code>LaptopRecommendation</code> object's data.</p>
<p>For example, lets say I have a list of <code>LaptopRecommendation</code> objects. I want to store any <code>LaptopRecommendation</code> object whose brand is Acer and laptop whose cost is less than 1300.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// list of LaptopRecommendation object</span>
<span class="hljs-keyword">var</span> recommendations = <span class="hljs-keyword">new</span> List&lt;LaptopRecommendation&gt;();
recommendations.Add(<span class="hljs-keyword">new</span> LaptopRecommendation(<span class="hljs-number">1200</span>, <span class="hljs-string">"acer"</span>));
recommendations.Add(<span class="hljs-keyword">new</span> LaptopRecommendation(<span class="hljs-number">600</span>, <span class="hljs-string">"dell"</span>));
<span class="hljs-comment">// list of laptop whose brand is acer and cost is less than 1300</span>
<span class="hljs-keyword">var</span> acerRecommendations = recommendations
                        .Where(recommendation =&gt;
                        {
                            (<span class="hljs-keyword">decimal</span> budget, <span class="hljs-keyword">string</span> brand) = recommendation;
                            <span class="hljs-keyword">return</span> brand <span class="hljs-keyword">is</span> <span class="hljs-string">"acer"</span> &amp;&amp; budget &lt; <span class="hljs-number">1300</span>;
                        })
                        .ToList();
Console.WriteLine(<span class="hljs-keyword">string</span>.Join(<span class="hljs-string">", "</span>, acerRecommendations.Select(x =&gt; x.brand)));
<span class="hljs-comment">// output: acer</span>
</code></pre>
<p>In <code>acerRecommendations</code>'s where filter, I've create two variables <code>budget</code> and <code>brand</code> of type <code>decimal</code> and <code>string</code> respectively and assigned them to <code>recommendation</code> (single object of <code>List&lt;LaptopRecommendation&gt;</code>). <code>recommendation</code> deconstructs and assign value in these newly created variables. <code>LaptopRecommendation</code>'s Deconstruct method contains two out params, they will be assigned to our two newly created variables(<code>budget</code> and <code>brand</code>).</p>
<p>Here are some deconstruction pattern:</p>
<h3 id="heading-property-pattern">Property pattern</h3>
<p>Property pattern is just a trick to deconstruct an object and match specific property within the object. What I mean by that is, it allows you to check for a specific condition within the property or field within that object. Eg: Check if an <code>Person</code> object's property <code>Age</code> is greater than 18. Here, we deconstruct <code>Person</code> object (extracting properties' values) and check the property <code>Age</code> if its greater than 18.</p>
<p>Syntax: <code>expression is {property1: someValue1, property2: someValue2, ...}</code></p>
<p>Eg: Using property pattern</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Person object.</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">Person</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> _age, <span class="hljs-keyword">string</span> _name, DateTime _dob</span>)</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = _age;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = _name;
    <span class="hljs-keyword">public</span> DateTime DateofBirth { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = _dob;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">string</span> <span class="hljs-title">ToString</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">return</span> <span class="hljs-string">$"Name: <span class="hljs-subst">{Name}</span>, Age: <span class="hljs-subst">{Age}</span>, Date of birth: <span class="hljs-subst">{DateofBirth}</span>"</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deconstruct</span>(<span class="hljs-params"><span class="hljs-keyword">out</span> <span class="hljs-keyword">int</span> personAge, <span class="hljs-keyword">out</span> <span class="hljs-keyword">string</span> personName, <span class="hljs-keyword">out</span> DateTime personDateofBirth</span>)</span> =&gt; (personAge, personName, personDateofBirth) = (Age, Name, DateofBirth);
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-comment">// initialize person object</span>
<span class="hljs-keyword">var</span> person1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-number">17</span>, <span class="hljs-string">"ram bahadur"</span>, DateTime.Parse(<span class="hljs-string">"2004-01-01"</span>));
Console.WriteLine(person1.ToString()); <span class="hljs-comment">// prints person object info</span>
<span class="hljs-keyword">if</span>(person1 <span class="hljs-keyword">is</span> { Age: &lt; <span class="hljs-number">21</span> })
    Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{person1.Name}</span> is not eligible to drink beer. Try milk."</span>);
<span class="hljs-keyword">else</span> Console.WriteLine(<span class="hljs-string">"Here is your beer. Drink responsibly."</span>);
<span class="hljs-comment">/* 
Output: 
Name: ram bahadur, Age: 17, Date of birth: 1/1/2004 12:00:00 AM
ram bahadur is not eligible to drink beer. Try milk.
*/</span>
</code></pre>
<p>Using property pattern when working with DateTime is very useful. Imagine a scenario where you need to check if date is between some particular time. Eg: I would like to know if a person is born in March.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">isBornInMarch</span>(<span class="hljs-params">DateTime dob</span>)</span>
{
    <span class="hljs-keyword">if</span> (dob <span class="hljs-keyword">is</span> { Month: <span class="hljs-number">3</span> })
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{person1.Name}</span> is born is march? <span class="hljs-subst">{isBornInMarch(person1.DateofBirth)}</span>."</span>); 
<span class="hljs-comment">/*
Output: ram bahadur is born is march? False.
*/</span>
</code></pre>
<p>Similarly, you can deconstruct an object and apply your conditional logic using property matching.</p>
<h3 id="heading-positional-pattern"><strong>Positional Pattern</strong></h3>
<p>Similar to property pattern which checks deconstruct an object and applies condition to property, positional pattern deconstruct object and checks for defined condition.</p>
<p>Imagine a scenario where you need to write a function which takes budget and brand as a parameter and return appropriate laptop.</p>
<p>Firstly, I will create an data structure to hold both of these value. This can be tuple as well but in this example I will create an <code>struct</code> to hold values. Here, object is of <code>struct</code> type but you can create of reference type as well.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">struct</span> <span class="hljs-title">LaptopRecommendation</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> _budget, <span class="hljs-keyword">string</span> _brand</span>)</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> budget = _budget;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> brand = _brand;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deconstruct</span>(<span class="hljs-params"><span class="hljs-keyword">out</span> <span class="hljs-keyword">decimal</span> LaptopBudget, <span class="hljs-keyword">out</span> <span class="hljs-keyword">string</span> LaptopBrand</span>)</span> =&gt; (LaptopBudget, LaptopBrand) = (budget, brand);
}
</code></pre>
<p>Main function to check the conditional logic:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">string</span> <span class="hljs-title">getLaptopDetail</span>(<span class="hljs-params">LaptopRecommendation info</span>)</span> =&gt; info <span class="hljs-keyword">switch</span>
{
    ( &lt;= <span class="hljs-number">1000</span> and &gt; <span class="hljs-number">500</span>, <span class="hljs-string">"acer"</span>) =&gt; <span class="hljs-string">"You should get a Acer Aspire 5."</span>,
    ( &lt;= <span class="hljs-number">1400</span> and &gt; <span class="hljs-number">1000</span>, <span class="hljs-string">"acer"</span>) =&gt; <span class="hljs-string">"You should get a Acer Nitro."</span>,
    ( &lt;= <span class="hljs-number">1500</span> and &gt; <span class="hljs-number">1000</span>, <span class="hljs-string">"acer"</span>) =&gt; <span class="hljs-string">"You should get a Acer Predator."</span>,
    ( &lt;= <span class="hljs-number">1000</span> and &gt; <span class="hljs-number">500</span>, <span class="hljs-string">"dell"</span>) =&gt; <span class="hljs-string">"You should get a Dell Inspiron."</span>,
    ( &lt;= <span class="hljs-number">1400</span> and &gt; <span class="hljs-number">1000</span>, <span class="hljs-string">"dell"</span>) =&gt; <span class="hljs-string">"You should get a Dell G series PC."</span>,
    ( &lt;= <span class="hljs-number">1500</span> and &gt; <span class="hljs-number">1000</span>, <span class="hljs-string">"dell"</span>) =&gt; <span class="hljs-string">"You should get a Dell Alienware."</span>,
    ( &gt;= <span class="hljs-number">3000</span>, <span class="hljs-keyword">object</span>) =&gt; <span class="hljs-string">"You should either get a Mac Pro M2 Series or a beefy razer series laptop. (I would get a beefy razer laptop)"</span>,
    _ =&gt; <span class="hljs-string">"I recommend you get any laptop from Lenovo Legion series."</span>,
};
</code></pre>
<h2 id="heading-more">More</h2>
<p>Before looking at some special pattern like List Pattern, I would like to make sure you understand ternary and null coalescing operator.</p>
<h3 id="heading-null-coalescing">Null coalescing</h3>
<p>Null coalescing was introduced in early version of C# (2.0). Null coalescing or <code>??</code> operator, is a way to handle null values. <code>??</code> is a binary operator, meaning it operates in two operands (left and right).</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">string</span> someData = <span class="hljs-literal">null</span>;
<span class="hljs-keyword">string</span> someDataBak = <span class="hljs-string">"N/A"</span>;
<span class="hljs-keyword">string</span> returnData = someData ?? someDataBak;
Console.WriteLine(returnData);
</code></pre>
<p>You can read <code>someData ?? someDataBak;</code> like, if <code>someData</code> not null, use it else use <code>someDataBak</code>.</p>
<h3 id="heading-ternary-operator">Ternary Operator</h3>
<p>Conditional operator or ternary operators is a way to perform conditional operation in a concise way. Syntax: <code>condition ? expression1 : expression2</code> or you can read this as: if <code>condition</code> is true, compute <code>expression1</code> else <code>expression2</code>.</p>
<p>Simple example to check user's age to vote using ternary:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">int</span> age = <span class="hljs-number">17</span>;
<span class="hljs-keyword">string</span> consoleMessage = age &gt; <span class="hljs-number">18</span> ? <span class="hljs-string">"Eliglble to vote."</span> : <span class="hljs-string">"Not eligible to vote"</span>;
Console.WriteLine(consoleMessage); 
<span class="hljs-comment">/*
Output: Not eligible to vote
*/</span>
</code></pre>
<h2 id="heading-special-pattern">Special Pattern</h2>
<h3 id="heading-var-pattern">Var pattern</h3>
<p>Var pattern was introduced in C# version 7.1. As the name say "var", var pattern is used when you want something to be stored in <code>var</code> and utilize it for some expression. Var pattern is very similar to type pattern. Instead of explicitly specifying type, you use <code>var</code>.</p>
<p>Example: Imagine you have a list of random objects. You want to know if this random list contains more than two animals.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> listOfAnimal = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">string</span>&gt;() { <span class="hljs-string">"dog"</span>, <span class="hljs-string">"cat"</span>, <span class="hljs-string">"rhino"</span>};
<span class="hljs-keyword">var</span> listOfRandomItems = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">object</span>&gt;() { <span class="hljs-string">"Ram"</span>, <span class="hljs-string">"hari"</span>, <span class="hljs-string">"John"</span>, <span class="hljs-number">421</span>, <span class="hljs-string">"bijay"</span>, <span class="hljs-string">"macafee"</span>, <span class="hljs-string">"apple"</span>, <span class="hljs-string">"dog"</span>, <span class="hljs-string">"cat"</span> };
<span class="hljs-function"><span class="hljs-keyword">bool</span> <span class="hljs-title">containsAnimal</span>(<span class="hljs-params">List&lt;<span class="hljs-keyword">object</span>&gt; randomStuff</span>)</span>
{
    <span class="hljs-keyword">return</span> randomStuff.Intersect(listOfAnimal) <span class="hljs-keyword">is</span> <span class="hljs-keyword">var</span> animalCount &amp;&amp; animalCount.Count() &gt; <span class="hljs-number">2</span>;
}
Console.WriteLine(<span class="hljs-string">$"listOfRandomItems contains animal? : <span class="hljs-subst">{containsAnimal(listOfRandomItems)}</span>"</span>);
<span class="hljs-comment">/*
Output: listOfRandomItems contains animal? : False
*/</span>
</code></pre>
<p>Instead of explicitly defining type like <code>List&lt;object&gt;</code> or <code>IEnumerable&lt;object&gt;</code>, you can simply use <code>var</code> pattern.</p>
<h3 id="heading-list-pattern">List pattern</h3>
<p>Introduced in C# version 11.0, list pattern is a very concise way to condition a list. Meaning list pattern helps you to filter and match certain condition in a list without having to write lengthy code.</p>
<p>For example, I have a list and I would like to check if the first value of that list is Blueskie, check third value name is Kumar, and check if last value of that list is Bret.</p>
<p>First case: Check if the first value is "Blueskie"</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> simpleListOfName = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">string</span>&gt; { <span class="hljs-string">"Blueskie"</span>, <span class="hljs-string">"Jon"</span>, <span class="hljs-string">"Jonsky"</span>, <span class="hljs-string">"Angel"</span>, <span class="hljs-string">"Bret"</span> };
<span class="hljs-keyword">if</span>(simpleListOfName <span class="hljs-keyword">is</span> [<span class="hljs-string">"Blueskie"</span>, _, _, _, _])
    Console.WriteLine(<span class="hljs-string">"First name is Blueskie."</span>);
<span class="hljs-comment">/*
Output: First name is Blueskie.
*/</span>
</code></pre>
<p>Here in the first case, I only care about 1st value of the list. So I discarded other values (<code>_</code>).</p>
<p>Second case: Check if the third value is "Kumar"</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">if</span>(simpleListOfName <span class="hljs-keyword">is</span> [_, _, <span class="hljs-string">"Kumar"</span>, _, _])
    Console.WriteLine(<span class="hljs-string">"Third name is Kumar."</span>);
<span class="hljs-keyword">else</span> Console.WriteLine(<span class="hljs-string">"Third name is not kumar."</span>);
<span class="hljs-comment">/*
Ouput: Third name is not kumar.
*/</span>
</code></pre>
<p>Here in the second case, I only care about 3rd value of the list. So I discarded other values (<code>_</code>).</p>
<p>Third case: Check if the last value is "Bret"</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">if</span> (simpleListOfName <span class="hljs-keyword">is</span> [.., <span class="hljs-string">"Bret"</span>])
    Console.WriteLine(<span class="hljs-string">"Last name is Bret."</span>);
</code></pre>
<p>Here in the third case, I only care about last value of the list. I don't really care about values till last. So, I can use slice sub-pattern ( <code>..</code> or two dots ). Slice pattern can be used only in list pattern. Also, C# compiler prohibits using more than one slice pattern.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711117450733/b7444bdb-2df3-4581-b15e-489e306a195f.png" alt class="image--center mx-auto" /></p>
<p>Another example using list pattern with switch expression. Imagine a scenario where you want print first and fourth value from a list.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> listOfNumbers = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt; {<span class="hljs-number">765</span>, <span class="hljs-number">2</span>, <span class="hljs-number">34</span>, <span class="hljs-number">5</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">33</span>, <span class="hljs-number">66</span> };
<span class="hljs-keyword">var</span> firstAndFourth = listOfNumbers <span class="hljs-keyword">is</span> [<span class="hljs-keyword">int</span> firstVal, _, _, <span class="hljs-keyword">int</span> fourthVal, ..] ? <span class="hljs-string">$"First num is:<span class="hljs-subst">{firstVal}</span>, fourth num is: <span class="hljs-subst">{fourthVal}</span>"</span> : <span class="hljs-string">"N/A"</span>;
Console.WriteLine(firstAndFourth);
<span class="hljs-comment">/*
Output: First num is:765, fourth num is: 5
*/</span>
</code></pre>
<p>Another example, print second and last value from a list using switch expression.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> listOfNumbers = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt; { <span class="hljs-number">765</span>, <span class="hljs-number">2</span>, <span class="hljs-number">34</span>, <span class="hljs-number">5</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">33</span>, <span class="hljs-number">66</span> };
<span class="hljs-keyword">var</span> numResult = listOfNumbers <span class="hljs-keyword">switch</span>
{
    [<span class="hljs-meta">_, int second, ..</span>] =&gt; <span class="hljs-string">$"Second num is: <span class="hljs-subst">{second}</span>"</span>,
    [<span class="hljs-meta">.., int last</span>] =&gt; <span class="hljs-string">$"Last num is: <span class="hljs-subst">{last}</span>"</span>,
    _ =&gt; <span class="hljs-string">"I dont care"</span>,
};
Console.WriteLine(numResult);
<span class="hljs-comment">/*
Ouput: Second num is: 2
*/</span>
</code></pre>
<p>In switch expression using list pattern when condition is matched, only that matched condition is executed. Therefore, above example only prints <code>Second num is: 2</code>.</p>
<p>Another example of list pattern is using it in CSV file. I have a CSV data of employees.</p>
<pre><code class="lang-plaintext">dawg@example.com,1,Tom,Thomson,founder
laura@example.com,4,Laura,Grey,manager
craig@example.com,8,Craig,Johnson,deputymanager
mary@example.com,77,Mary,Jenkins,engineer
jamie@example.com,101,Jamie,Smith,intern
mikey@gmail.com,00,Mike,Paul,clown
</code></pre>
<p>I would like to provide some information based on the employee. Like, greet them if they are manager, and let them know how early they joined the company (based on their id which is sequential).</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> <span class="hljs-keyword">var</span> emp = <span class="hljs-keyword">new</span> StreamReader(<span class="hljs-string">"../../../email.csv"</span>);
<span class="hljs-keyword">while</span> (!emp.EndOfStream)
{
    <span class="hljs-keyword">string</span>[]? empInfo = emp.ReadLine()?.Split(<span class="hljs-string">','</span>);
    <span class="hljs-keyword">var</span> greetAccordingly = empInfo <span class="hljs-keyword">switch</span>
    {
        [<span class="hljs-meta">_, _, _, string lastName, <span class="hljs-meta-string">"manager"</span></span>] =&gt; <span class="hljs-string">$"Good Evening, Manager <span class="hljs-subst">{lastName}</span>."</span>,
        [<span class="hljs-meta">_, string id, _, ..</span>] =&gt; <span class="hljs-keyword">int</span>.TryParse(id, <span class="hljs-keyword">out</span> <span class="hljs-keyword">int</span> empId) &amp;&amp; (empId &gt; <span class="hljs-number">2</span> &amp;&amp; empId &lt; <span class="hljs-number">10</span>) ? <span class="hljs-string">"You are top 10 employee to join da Company."</span> : <span class="hljs-string">"You joined the company after 10 people joined."</span>,
        [<span class="hljs-meta">_, string id, ..</span>] =&gt; <span class="hljs-keyword">int</span>.TryParse(id, <span class="hljs-keyword">out</span> <span class="hljs-keyword">int</span> empId) &amp;&amp; empId <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> ? <span class="hljs-string">"Hello Mr CEO."</span> : <span class="hljs-string">"Well, Hello there :-) "</span>,
        _ =&gt; <span class="hljs-string">"Nothing matched."</span>
    };
    Console.WriteLine(greetAccordingly);
}
<span class="hljs-comment">/*
Output: 
        You joined the company after 10 people joined.
        Good Evening, Manager Grey.
        You are top 10 employee to join da Company.
        You joined the company after 10 people joined.
        You joined the company after 10 people joined.
        You joined the company after 10 people joined.
*/</span>
</code></pre>
<p>Another example, check employee email for verification (on same above CSV file). Basically, email with the extension @example.com is verified.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> <span class="hljs-keyword">var</span> emp = <span class="hljs-keyword">new</span> StreamReader(<span class="hljs-string">"../../../email.csv"</span>);
<span class="hljs-keyword">while</span> (!emp.EndOfStream)
{
    <span class="hljs-keyword">string</span>[]? empInfo = emp.ReadLine()?.Split(<span class="hljs-string">','</span>);
    <span class="hljs-keyword">var</span> checkVerifiedEmployee = empInfo <span class="hljs-keyword">switch</span>
    {
        [<span class="hljs-meta">string email, ..</span>] =&gt; email.Split(<span class="hljs-string">"@"</span>).Contains(<span class="hljs-string">"example.com"</span>) ? <span class="hljs-string">$"<span class="hljs-subst">{email}</span> is Verified Example worker."</span> : <span class="hljs-string">$"<span class="hljs-subst">{email}</span> is Unverified user."</span>,
        _ =&gt; <span class="hljs-string">"Nothing matched."</span>
    };
    Console.WriteLine(checkVerifiedEmployee);
}
<span class="hljs-comment">/* Output:
           dawg@example.com is Verified Example worker.
           laura@example.com is Verified Example worker.
           craig@example.com is Verified Example worker.
           mary@example.com is Verified Example worker.
           jamie@example.com is Verified Example worker.
           mikey@gmail.com is Unverified user.
*/</span>
</code></pre>
<p>You can learn more about List pattern :</p>
<ol>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-11.0/list-patterns">Microsoft docs</a></p>
</li>
<li><p><a target="_blank" href="https://endjin.com/blog/2023/03/dotnet-csharp-11-pattern-matching-lists">endjin's blog</a></p>
</li>
</ol>
<h2 id="heading-summary">Summary</h2>
<ul>
<li><p><strong>Pattern matching</strong> offers a versatile way to check data against various condition, including types, values, relational operators, and object properties.</p>
</li>
<li><p><strong>Basic Patterns</strong>: Describes constant, relational, type, and declaration patterns with examples.</p>
</li>
<li><p><strong>Switch Expression</strong>: Switch expressions introduced in C# 8.0 allow chaining of pattern matching conditions, which results to more concise and readable code compared to traditional if-else statements.</p>
</li>
<li><p><strong>Deconstruct method</strong> is used to extract specific properties from objects for easier manipulation.</p>
</li>
<li><p>You can combine multiple relational operators with logical operators (<code>&amp;&amp;</code> - and, <code>||</code> - or) to create complex conditions within a single pattern.</p>
</li>
<li><p><strong>Discard Pattern</strong>: Use the <code>_</code> pattern to ignore irrelevant values during matching.</p>
</li>
<li><p><strong>Deconstruction Patterns</strong>: Describes deconstruction patterns and their use in extracting information from objects. Pattern matching facilitates deconstructing objects to extract specific properties, simplifying data manipulation.</p>
</li>
<li><p><strong>Null Coalescing and Ternary Operators</strong>: Briefly discusses null coalescing and ternary operators for handling null values and conditional operations.</p>
</li>
<li><p><strong>Special Patterns</strong>: Covers var pattern and list pattern, explaining their syntax and applications with examples.</p>
</li>
<li><p>Using clear and descriptive patterns, code becomes easier to understand and scalable.</p>
</li>
</ul>
<p><a target="_blank" href="https://github.com/sushantpt/PatternMatchingSolution">Sourcecode.</a></p>
]]></content:encoded></item><item><title><![CDATA[SOLID Principles]]></title><description><![CDATA[Some of the most important things to consider when designing a software is to make software entities reusable, flexible, scalable, robust, and maintainable. Implementing SOLID principles can impacts these aspects of software design in a good way.
Int...]]></description><link>https://sushantpant.com.np/solid-principles</link><guid isPermaLink="true">https://sushantpant.com.np/solid-principles</guid><category><![CDATA[SOLID principles]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[software design]]></category><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Sat, 10 Feb 2024 19:15:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707591732123/96df48d3-2533-4b93-9272-1de6a19d4bb3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Some of the most important things to consider when designing a software is to make software entities reusable, flexible, scalable, robust, and maintainable. Implementing SOLID principles can impacts these aspects of software design in a good way.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>SOLID is an abbreviation which translates to some set of principles created by Robert Cecil Martin a.k.a <a target="_blank" href="http://cleancoder.com">Uncle Bob</a>. SOLID principle states that the object must have single responsibility (S), it must be open for extensions but closed for modification (O), child class must be able to replace parent class (L), unwanted behavior must be excluded from the object (I), use abstractions to ensure modules depends on interfaces rather than concrete implementation (D).</p>
<h2 id="heading-single-responsibility">Single Responsibility</h2>
<p>First principle of SOLID stands for Single Responsibility. It means that any unit or block of code, whether its a class, or method, or a function must have single responsibility. Each unit should be responsible for only one functionality. This makes the software more easy to debug. Therefore, it states that your unit of code must be specific.</p>
<h3 id="heading-demonstration">Demonstration</h3>
<p>Here's an scenario demonstrating good design implementing single responsibility and bad design not implementing it.</p>
<p>Imagine a auth module in an web application where user needs to register themself. If user inputs correct information, they will receive an email confirming their identity for this web application.</p>
<p>First approach. A more naive (Not implementing Single Responsibility).</p>
<pre><code class="lang-csharp"><span class="hljs-comment">/* Data model used for demonstration */</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">UserInputs</span>
{
    <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> UserName { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Email { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Password { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">Auth</span>(<span class="hljs-params">UserInputs inputs</span>)</span>
{
    <span class="hljs-keyword">private</span> UserInputs _inputs = inputs;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Users = [<span class="hljs-string">"ram"</span>, <span class="hljs-string">"sam"</span>, <span class="hljs-string">"john"</span>, <span class="hljs-string">"tom"</span>, <span class="hljs-string">"hari"</span>];
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Emails = [<span class="hljs-string">"ram@mail.com"</span>, <span class="hljs-string">"sam@mail.com"</span>, <span class="hljs-string">"john@mail.com"</span>, <span class="hljs-string">"tom@mail.com"</span>, <span class="hljs-string">"hari@mail.com"</span>];

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUser</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.UserName) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Email) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Password))
        {
            Console.WriteLine(<span class="hljs-string">"Username, Email and Password are required field."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Emails.Contains(_inputs.Email))
        {
            Console.WriteLine(<span class="hljs-string">"Email already exists. Please sign in."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Users.Contains(_inputs.UserName))
        {
            Console.WriteLine(<span class="hljs-string">"User name already exists."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (_inputs.Password.Length &lt; <span class="hljs-number">8</span>)
        {
            Console.WriteLine(<span class="hljs-string">"Password length must be atleast 8 characters."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        Console.WriteLine(<span class="hljs-string">$"New user <span class="hljs-subst">{_inputs.UserName}</span> has been created."</span>);
        <span class="hljs-comment">// user's inputs seems fine, now send them email confirming their identity.</span>
        Console.WriteLine(<span class="hljs-string">"--- New email from Auth Module ---"</span>);
        Console.WriteLine(<span class="hljs-string">$"Account has been created successfully. \n"</span> +
            <span class="hljs-string">$"Username: <span class="hljs-subst">{_inputs.UserName}</span> \n"</span> +
            <span class="hljs-string">$"Email: <span class="hljs-subst">{_inputs.Email}</span> \n"</span> +
            <span class="hljs-string">$"Password: <span class="hljs-subst">{_inputs.Password}</span> \n"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
}
</code></pre>
<p>Above code violates the Single Responsibility Principle as the method should have a singular focus. <code>VerifyUser()</code> has multiple responsibility like validating user, creating user, and sending confirmation email. If I had to modify my validation logic, I need to modify <code>VerifyUser()</code>, which consists of multiple responsibility. Therefore, this codebase will become hard to test and maintain.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code and output when single responsibility principle is applied</span>
<span class="hljs-keyword">var</span> user1 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"sushant"</span>,
    Email = <span class="hljs-string">"sushant@mail.com"</span>,
    Password = <span class="hljs-string">"password"</span>
};

badExampleCode::Auth badExample = <span class="hljs-keyword">new</span> badExampleCode::Auth(user1);
badExample.VerifyUser();
<span class="hljs-comment">/*
Output: New user sushant has been created.
        --- New email from Auth Module ---
        Account has been created successfully.
        Username: sushant
        Email: sushant@mail.com
        Password: password
*/</span>
</code></pre>
<blockquote>
<p>Before moving on, you can try refactoring it to enhance the design.</p>
</blockquote>
<p>Here's another approach which is much more better than the first approach and follows single responsibility principle.</p>
<p>In the above code, we need to separate 3 things to achieve single responsibility: Validation, Registration, and Confirmation email. So I will add: <code>ValidateUser()</code> for validation, <code>RegisterUser()</code> for registration and <code>SendEmail()</code> for email confirmation. Sending email is useful in other modules as well. So I will create a separate class for it.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">Auth</span>(<span class="hljs-params">UserInputs inputs</span>)</span>
{
    <span class="hljs-keyword">private</span> UserInputs _inputs = inputs;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Users = [<span class="hljs-string">"ram"</span>, <span class="hljs-string">"sam"</span>, <span class="hljs-string">"john"</span>, <span class="hljs-string">"tom"</span>, <span class="hljs-string">"hari"</span>];
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Emails = [<span class="hljs-string">"ram@mail.com"</span>, <span class="hljs-string">"sam@mail.com"</span>, <span class="hljs-string">"john@mail.com"</span>, <span class="hljs-string">"tom@mail.com"</span>, <span class="hljs-string">"hari@mail.com"</span>];

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUser</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (ValidateUser() &amp;&amp; RegisterUser())
        {
            <span class="hljs-comment">/* when everthing goes fine */</span>
            <span class="hljs-keyword">string</span> toEmail = _inputs.Email;
            <span class="hljs-keyword">string</span> subject = <span class="hljs-string">"New email from Auth Module"</span>;
            <span class="hljs-keyword">string</span> body = <span class="hljs-string">$"Account has been created successfully. \n"</span> +
                            <span class="hljs-string">$"Username: <span class="hljs-subst">{_inputs.UserName}</span> \n"</span> +
                            <span class="hljs-string">$"Email: <span class="hljs-subst">{_inputs.Email}</span> \n"</span> +
                            <span class="hljs-string">$"Password: <span class="hljs-subst">{_inputs.Password}</span> \n"</span>;
            EmailHelper email = <span class="hljs-keyword">new</span> EmailHelper();
            email.SendEmail(toEmail, subject, body);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-comment">/* when something goes wrong */</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">ValidateUser</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.UserName) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Email) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Password))
        {
            Console.WriteLine(<span class="hljs-string">"Username, Email and Password are required field."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Emails.Contains(_inputs.Email))
        {
            Console.WriteLine(<span class="hljs-string">"Email already exists. Please sign in."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Users.Contains(_inputs.UserName))
        {
            Console.WriteLine(<span class="hljs-string">"User name already exists."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (_inputs.Password.Length &lt; <span class="hljs-number">8</span>)
        {
            Console.WriteLine(<span class="hljs-string">"Password length must be atleast 8 characters."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">RegisterUser</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"New user <span class="hljs-subst">{_inputs.UserName}</span> has been created."</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmailHelper</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> to, <span class="hljs-keyword">string</span> subject, <span class="hljs-keyword">string</span> body</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Email to: <span class="hljs-subst">{to}</span>"</span>);
        Console.WriteLine(<span class="hljs-string">$"Subject: <span class="hljs-subst">{subject}</span>"</span>);
        Console.WriteLine(<span class="hljs-string">$"Body: <span class="hljs-subst">{body}</span>"</span>);
    }
}
</code></pre>
<p>This is much better design and follows single responsibility principle. This codebase promotes clearer separation of concerns which is organized, has better readability, flexible, and is easy to maintain. This results in overall betterment of software design.</p>
<p>At the end, building robust, flexible, and scalable software is the end goal of an ever evolving software requirements which is emphasized by following the single responsibility principle.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code and output when single responsibility principle is applied</span>
<span class="hljs-keyword">var</span> user2 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"jon"</span>,
    Email = <span class="hljs-string">"bones@mail.com"</span>,
    Password = <span class="hljs-string">"jonjones11"</span>
};
goodExampleCode::Auth goodExample = <span class="hljs-keyword">new</span> goodExampleCode::Auth(user2);
goodExample.VerifyUser();

<span class="hljs-comment">/*
Output: New user jon has been created.
        Email to: bones@mail.com
        Subject: New email from Auth Module
        Body: Account has been created successfully.
        Username: jon
        Email: bones@mail.com
        Password: jonjones11
*/</span>
</code></pre>
<h3 id="heading-takeaway-from-single-responsibility-principle">Takeaway from Single Responsibility Principle</h3>
<p>A whole single component may consist many pieces of components. A better software design would be to have each component have a single responsibility. It doesn't matter whether we consider the component as a whole or as individual pieces doing their part. Each component must have a specific responsibility.</p>
<p>In the first approach, <code>VerifyUser()</code> component had multiple responsibility. We decompose that and created multiple separate component. Finally, we compose all the component as whole.</p>
<h2 id="heading-openclose-principle">Open/Close Principle</h2>
<p>Second principle of SOLID stands for Open/Close Principle. It means that an software entity must be open for extension and close for modification. Software entities can be class, module, method, or a function. Therefore, it states that your software entities should allow new functionalities without hampering existing behavior. To achieve Open/Close principle, we mostly use inheritance and interfaces.</p>
<h3 id="heading-demonstration-1">Demonstration</h3>
<p>To demonstrate Open/Close principle, I will use the same example I used above (Auth module in an web application).</p>
<p>Open/Close principle state an entity should be open for extension and close for modification. I will create an abstract class which consist authentication logic.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Authenticate</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Users = [<span class="hljs-string">"ram"</span>, <span class="hljs-string">"sam"</span>, <span class="hljs-string">"john"</span>, <span class="hljs-string">"tom"</span>, <span class="hljs-string">"hari"</span>];
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span>[] Emails = [<span class="hljs-string">"ram@mail.com"</span>, <span class="hljs-string">"sam@mail.com"</span>, <span class="hljs-string">"john@mail.com"</span>, <span class="hljs-string">"tom@mail.com"</span>, <span class="hljs-string">"hari@mail.com"</span>];

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUser</span>(<span class="hljs-params">UserInputs _inputs</span>)</span>
    {
        <span class="hljs-comment">/* when everthing goes fine */</span>
        <span class="hljs-keyword">if</span> (ValidateUser(_inputs) &amp;&amp; RegisterUser(_inputs))
        {
            <span class="hljs-keyword">string</span> toEmail = _inputs.Email;
            <span class="hljs-keyword">string</span> subject = <span class="hljs-string">"New email from Auth Module"</span>;
            <span class="hljs-keyword">string</span> body = <span class="hljs-string">$"Account has been created successfully. \n"</span> +
                            <span class="hljs-string">$"Username: <span class="hljs-subst">{_inputs.UserName}</span> \n"</span> +
                            <span class="hljs-string">$"Email: <span class="hljs-subst">{_inputs.Email}</span> \n"</span> +
                            <span class="hljs-string">$"Password: <span class="hljs-subst">{_inputs.Password}</span> \n"</span>;

            EmailHelper email = <span class="hljs-keyword">new</span> EmailHelper();
            email.SendEmail(toEmail, subject, body);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }

        <span class="hljs-comment">/* when something goes wrong */</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">ValidateUser</span>(<span class="hljs-params">UserInputs _inputs</span>)</span>
    {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.UserName) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Email) || <span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(_inputs.Password))
        {
            Console.WriteLine(<span class="hljs-string">"Username, Email and Password are required field."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Emails.Contains(_inputs.Email))
        {
            Console.WriteLine(<span class="hljs-string">"Email already exists. Please sign in."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (Users.Contains(_inputs.UserName))
        {
            Console.WriteLine(<span class="hljs-string">"User name already exists."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (_inputs.Password.Length &lt; <span class="hljs-number">8</span>)
        {
            Console.WriteLine(<span class="hljs-string">"Password length must be atleast 8 characters."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">RegisterUser</span>(<span class="hljs-params">UserInputs _inputs</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"New user <span class="hljs-subst">{_inputs.UserName}</span> has been created."</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
}
</code></pre>
<p>When I implement this abstract class, authentication logic will be close for modification but open for extension.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Auth</span> : <span class="hljs-title">Authenticate</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsPastUser</span>(<span class="hljs-params">UserInputs _inputs</span>)</span>
    {
        <span class="hljs-keyword">var</span> pastUserList = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">string</span>&gt;()
        {
            <span class="hljs-string">"volk@mail.com"</span>, <span class="hljs-string">"chael@mail.com"</span>, <span class="hljs-string">"topuria@mail.com"</span>, <span class="hljs-string">"islam@mail.com"</span>, <span class="hljs-string">"sushantpant@mail.com"</span>
        };

        <span class="hljs-keyword">if</span> (pastUserList.Contains(_inputs.Email))
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<p>Here, <code>Auth</code> implements <code>Authenticate</code> abstract class. <code>Authenticate</code> is close for modification. It is not possible to override <code>VerifyUser()</code> because it is not marked to be overridden (<code>virtual</code>). I added a new method <code>IsPastUser()</code> to check if the user had already registered before. I can extends this class and add more features as I want. This makes <code>Auth</code> class do exactly what it mean to do that is to authenticate (Close for modification) and add more features (Open for extension).</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code and output</span>
<span class="hljs-keyword">var</span> user3 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"sushantpant"</span>,
    Email = <span class="hljs-string">"sushantpant@mail.com"</span>,
    Password = <span class="hljs-string">"p@ssWo3d"</span>
};

openclosePrinciple::Auth openCloseP = <span class="hljs-keyword">new</span> openclosePrinciple::Auth();
openCloseP.VerifyUser(user3);
<span class="hljs-keyword">if</span> (openCloseP.IsPastUser(user3))
    Console.WriteLine(<span class="hljs-string">$"Welcome back <span class="hljs-subst">{user3.UserName}</span>."</span>);

<span class="hljs-comment">/*
Output: New user sushantpant has been created.
        Email to: sushantpant@mail.com
        Subject: New email from Auth Module
        Body: Account has been created successfully.
        Username: sushantpant
        Email: sushantpant@mail.com
        Password: p@ssWo3d

        Welcome back sushantpant.
*/</span>
</code></pre>
<h3 id="heading-takeaway-from-openclose-principle">Takeaway from Open/Close Principle</h3>
<p>The Open/Closed Principle emphasizes software entities to be open for extension but closed for modification. This makes adding new functionalities and behavior to a software entity easy without hampering the default behavior of other components.</p>
<h2 id="heading-liskov-substitution-principle">Liskov Substitution Principle</h2>
<p>Third principle of SOLID stands for Liskov substitution Principle. It means that a child class should be able to replace a parent class, inheriting all the behaviors of the parent class. Therefore, according to the Liskov Substitution Principle, objects of the parent class can be replaced with objects of the child class without affecting the correctness of the program. Applying Liskov substitution principle is possible by using inheritance. If you need a new object with new functionalities but majority of it being same as some other object, you just extend that object and add your new functionalities and behavior.</p>
<h3 id="heading-demonstration-2">Demonstration</h3>
<p>Imagine a new requirement in our previous example of Auth Module.</p>
<p>For example: Send a discount coupon to a new user.</p>
<p>Firstly, we don't want to do any changes in the original <code>Auth</code> object. Just add a new feature to send discount coupon. To do this, I will create a new class called <code>AuthWithDiscount</code> which will be derived from <code>Auth</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthWithDiscount</span> : <span class="hljs-title">Auth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendDiscountCoupon</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email</span>)</span>
    {
        Random rand = <span class="hljs-keyword">new</span> Random();
        <span class="hljs-keyword">int</span> discount = rand.Next(<span class="hljs-number">0</span>, <span class="hljs-number">30</span>);

        <span class="hljs-keyword">var</span> arr = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>, <span class="hljs-string">"Z"</span>, <span class="hljs-string">"X"</span> };
        <span class="hljs-keyword">var</span> discountCoupon = <span class="hljs-keyword">new</span> StringBuilder();
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++)
        {
            discountCoupon.Append(arr[rand.Next(i)]);
            discountCoupon.Append(rand.Next(i+i));
        }

        <span class="hljs-keyword">string</span> subject = <span class="hljs-string">"Discount for new user."</span>;
        <span class="hljs-keyword">string</span> body = <span class="hljs-string">$"Thanks for joining. To celebrate this, here is a discount of: <span class="hljs-subst">{discount}</span>%. "</span> +
            <span class="hljs-string">$"Discount coupon: <span class="hljs-subst">{discountCoupon}</span>"</span>;
        EmailHelper emailHelper = <span class="hljs-keyword">new</span> EmailHelper();
        emailHelper.SendEmail(email, subject, body);
    }
}
</code></pre>
<p>Here, <code>AuthWithDiscount</code> (child class) will have all behavior of <code>Auth</code> (parent class), with additional behavior. Now back to definition of Liskov substitution principle, child class should be able to replace parent class. In our case, <code>AuthWithDiscount</code> will replace <code>Auth</code> class and still maintain the same functionality of authenticating.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code and output</span>
<span class="hljs-keyword">var</span> user4 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"dawg"</span>,
    Email = <span class="hljs-string">"dawg@mail.com"</span>,
    Password = <span class="hljs-string">"handshakeleema"</span>
};

AuthWithDiscount authWithDiscount = <span class="hljs-keyword">new</span> AuthWithDiscount();
<span class="hljs-keyword">if</span>(authWithDiscount.VerifyUser(user4))
    authWithDiscount.SendDiscountCoupon(user4.Email);

<span class="hljs-comment">/*
Output: New user dawg has been created.
        Email to: dawg@mail.com
        Subject: New email from Auth Module
        Body: Account has been created successfully.
        Username: dawg
        Email: dawg@mail.com
        Password: handshakeleema

        Email to: dawg@mail.com
        Subject: Discount for new user.
        Body: Thanks for joining. To celebrate this, here is a discount of: 16%. Discount coupon: A0A0A1
*/</span>
</code></pre>
<h3 id="heading-takeaway-from-liskov-substitution-principle">Takeaway from Liskov Substitution Principle</h3>
<p>The Liskov substitution Principle (derived class should be able to replace base class) promotes code reusability, maintainability, scalability, and extensibility of an software object. This results in a more flexible software design.</p>
<h2 id="heading-interface-segregation">Interface Segregation</h2>
<p>Fourth principle of SOLID stands for Interface Segregation. Interfaces are use to define the behavior that a class has to provide. The Interface segregation principle suggests that interface must be tailored to object. It must not contain irrelevant functionalities. If a class/object only needs a subset of functionalities from an interface, it should not be burdened with unnecessary methods or properties. By defining interfaces that are object-specific, classes can implement only the interfaces that are relevant to their functionality. This promotes a cleaner and more modular design approach.</p>
<h3 id="heading-demonstration-3">Demonstration</h3>
<p>I will continue with my previous example of Auth module.</p>
<p>In Auth module, we can add a lot of feature. Let us consider 3 ways a user can register: social media account, email account, or phone number. For user from North America, all these 3 options are available. For APAC user, only social media and email account is available.</p>
<p>There can be multiple type of authentication. Like: auth with discount, auth for APAC user, auth for North America user, and more. Specifically auth has specific behavior. APAC has some other specific behavior. Therefore, I will create set of behavior for auth with email, auth with mobile no, and auth with social media.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IEmailAuth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsEmailConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email</span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IMobileAuth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithMobile</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> mobileNo, <span class="hljs-keyword">string</span> password</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsMobileConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> mobileNo</span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">ISocialMediaAuth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithSocialMedia</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> socialMediaId, <span class="hljs-keyword">string</span> userName, <span class="hljs-keyword">string</span> password</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsSocialMediaConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> userName</span>)</span>;
}
</code></pre>
<p>APAC user can register themself by using email address or social media. Therefore, auth for APAC user will implement <code>IEmailAuth</code>, and <code>ISocialMediaAuth</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthForAPAC</span> : <span class="hljs-title">IEmailAuth</span>, <span class="hljs-title">ISocialMediaAuth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsEmailConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email</span>)</span>
    {
        <span class="hljs-keyword">if</span> (email <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; email.Contains(<span class="hljs-string">'@'</span>))
        {
            Console.WriteLine(<span class="hljs-string">"Email is verified."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsSocialMediaConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> userName</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfSocialMediaUsername = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon"</span>, <span class="hljs-string">"dawg"</span>, <span class="hljs-string">"sushant"</span> };
        <span class="hljs-keyword">if</span> (userName <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfSocialMediaUsername.Contains(userName))
        {
            Console.WriteLine(<span class="hljs-string">"Social media is verified."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">if</span> (email.Contains(<span class="hljs-string">'@'</span>) &amp;&amp; email.Contains(<span class="hljs-string">'.'</span>) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithSocialMedia</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> socialMediaId, <span class="hljs-keyword">string</span> userName, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfSocialMediaUsername = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon"</span>, <span class="hljs-string">"dawg"</span>, <span class="hljs-string">"sushant"</span> };
        <span class="hljs-keyword">if</span> (socialMediaId &gt; <span class="hljs-number">1</span> &amp;&amp; userName <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfSocialMediaUsername.Contains(userName) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<p>In the above code, only functionalities that is relevant to auth for APAC user is added.</p>
<p>Now for american user, they will have options to register with email, mobile or social media handle. Therefore, it will implement <code>IEmailAuth</code>, <code>IMobileAuth</code>, and <code>ISocialMediaAuth</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthForAmerica</span> : <span class="hljs-title">IEmailAuth</span>, <span class="hljs-title">ISocialMediaAuth</span>, <span class="hljs-title">IMobileAuth</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsEmailConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email</span>)</span>
    {
        <span class="hljs-keyword">if</span>(email <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; email.Contains(<span class="hljs-string">'@'</span>))
        {
            Console.WriteLine(<span class="hljs-string">"Email is verified."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsMobileConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> mobileNo</span>)</span>
    {
        <span class="hljs-keyword">if</span> (mobileNo <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; mobileNo.Contains(<span class="hljs-string">"+123"</span>) &amp;&amp; mobileNo.Length <span class="hljs-keyword">is</span> <span class="hljs-number">10</span>)
        {
            Console.WriteLine(<span class="hljs-string">"Mobile is verified."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsSocialMediaConfirmed</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> userName</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfSocialMediaUsername = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon"</span>, <span class="hljs-string">"dawg"</span>, <span class="hljs-string">"sushant"</span> };
        <span class="hljs-keyword">if</span> (userName <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfSocialMediaUsername.Contains(userName))
        {
            Console.WriteLine(<span class="hljs-string">"Social media is verified."</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">if</span>(email.Contains(<span class="hljs-string">'@'</span>) &amp;&amp; email.Contains(<span class="hljs-string">'.'</span>) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithMobile</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> mobileNo, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">if</span> (mobileNo <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; mobileNo.Contains(<span class="hljs-string">"+123"</span>) &amp;&amp; mobileNo.Length <span class="hljs-keyword">is</span> <span class="hljs-number">10</span> &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyUserWithSocialMedia</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> socialMediaId, <span class="hljs-keyword">string</span> userName, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfSocialMediaUsername = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon"</span>, <span class="hljs-string">"dawg"</span>, <span class="hljs-string">"sushant"</span> };
        <span class="hljs-keyword">if</span> (socialMediaId &gt; <span class="hljs-number">1</span> &amp;&amp; userName <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfSocialMediaUsername.Contains(userName) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<p>Here, only functionalities that is relevant to auth for american user is added.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code and output</span>
<span class="hljs-keyword">var</span> user5 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"rambdr"</span>,
    Email = <span class="hljs-string">"rambdr@mail.com"</span>,
    Password = <span class="hljs-string">"mteverest8848"</span>
};
AuthForAPAC authForAPAC = <span class="hljs-keyword">new</span> AuthForAPAC();
<span class="hljs-keyword">var</span> verify = authForAPAC.VerifyUserWithEmail(user5.Email, user5.Password); <span class="hljs-comment">// register with email</span>
<span class="hljs-keyword">if</span> (verify)
    Console.WriteLine(<span class="hljs-string">$"New account registered with email: <span class="hljs-subst">{user5.Email}</span>"</span>);
<span class="hljs-comment">/*
Output: New account registered with email: rambdr@mail.com
*/</span>
</code></pre>
<p>Finally, interface segregation suggests breaking down complex entities into small relevant entities (decomposition). This promotes flexibility and loose coupling (less attachment with other object) in software design.</p>
<h3 id="heading-takeaway-from-interface-segregation-principle">Takeaway from Interface Segregation Principle</h3>
<p>The Interface segregation principle suggest breaking down relevant functionalities into interface and only implement it to class where it is required. This results in a more flexible software design which is modular, flexible, and maintainable.</p>
<h2 id="heading-dependency-inversion">Dependency Inversion</h2>
<p>Fifth and final principle of SOLID stands for Dependency inversion principle. Dependency inversion principle states multiple rules.</p>
<ul>
<li><p>Firstly, it state that a higher level object should never depend on a concrete lower level object. Meaning, high-level modules should not directly rely on the specific implementations of low-level modules. Instead, both high-level and low-level modules should depend on abstractions, such as interfaces or abstract classes.</p>
</li>
<li><p>This bring up to the second rule, abstractions should not depend upon on details. Abstraction should not be coupled to the specific implementation details of lower-level modules.</p>
</li>
<li><p>Finally, the third rule states that details should depend on abstractions.</p>
</li>
</ul>
<p>Covering up all, dependency inversion state that there must be an abstraction hiding implementation (use interface) and specify implementation to that interface (dependency injection). (Higher level module is an interface and lower level module is the implementation of that interface)</p>
<h3 id="heading-demonstration-4">Demonstration</h3>
<p>To demonstrate dependency inversion principle, I will work on same above example of auth module. Basically, there will be 2 auth option: auth with facebook and auth with email. So I will create 2 separate interface:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IAuthWithFacebook</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyFacebookAcc</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> facebookId, <span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IAuthWithEmail</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyAcc</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>;
}
</code></pre>
<p>Both of these auth option: auth with facebook <code>IAuthWithFacebook</code> and auth with email <code>IAuthWithEmail</code> will have a single concrete implementation. Therefore, I will create 2 classes <code>AuthWithFacebook</code> and <code>AuthWithEmail</code> to implement these interfaces.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthWithFacebook</span> : <span class="hljs-title">IAuthWithFacebook</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyFacebookAcc</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> facebookId, <span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfSocialMediaUsername = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon"</span>, <span class="hljs-string">"dawg"</span>, <span class="hljs-string">"sushant"</span>, <span class="hljs-string">"joerogan"</span> };
        <span class="hljs-keyword">if</span> (facebookId <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfSocialMediaUsername.Contains(facebookId) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthWithEmail</span> : <span class="hljs-title">IAuthWithEmail</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyAcc</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">var</span> listOfEmail = <span class="hljs-keyword">new</span> <span class="hljs-keyword">string</span>[] { <span class="hljs-string">"jon@mail.com"</span>, <span class="hljs-string">"dawg@mail.com"</span>, <span class="hljs-string">"sushant@mail.com"</span>, <span class="hljs-string">"joerogan@mail.com"</span> };
        <span class="hljs-keyword">if</span> (email <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> &amp;&amp; listOfEmail.Contains(email) &amp;&amp; password.Length &gt; <span class="hljs-number">8</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<p>The implementations (<code>AuthWithFacebook</code> and <code>AuthWithEmail</code>) depend on these interfaces, which is in line with the Dependency Inversion Principle. This allows the high-level modules (implementation) to remain decoupled from the specifics of how authentication is performed. This ensures that high-level modules depend on abstractions (interfaces), while the details of implementations are encapsulated within the low-level modules.</p>
<p>Then I will create another class called <code>CallingCode</code> to demonstrate dependency inversion.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">CallingCode</span>(<span class="hljs-params">IAuthWithFacebook _authWithFacebook</span>)</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IAuthWithFacebook authWithFacebook = _authWithFacebook;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">VerifyAuth</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> userName, <span class="hljs-keyword">string</span> email, <span class="hljs-keyword">string</span> password</span>)</span>
    {
        <span class="hljs-keyword">return</span> _authWithFacebook.VerifyFacebookAcc(userName, email, password);
    }
}
</code></pre>
<p>Here, <code>CallingCode</code> takes <code>IAuthWithFacebook</code> as argument by using latest C# 12 feature: primary constructor. <code>VerifyAuth()</code> does nothing but redirects to <code>IAuthWithFacebook</code>'s method.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// main calling code</span>
<span class="hljs-keyword">var</span> user6 = <span class="hljs-keyword">new</span> UserInputs()
{
    UserName = <span class="hljs-string">"joerogan"</span>,
    Email = <span class="hljs-string">"joerogan@mail.com"</span>,
    Password = <span class="hljs-string">"joeroganexperience"</span>
};
<span class="hljs-keyword">var</span> authWithFacebookObj = <span class="hljs-keyword">new</span> AuthWithFacebook();
CallingCode callingCode = <span class="hljs-keyword">new</span> CallingCode(authWithFacebookObj);
<span class="hljs-keyword">var</span> facebookAuth = callingCode.VerifyAuth(user6.UserName, user6.Email, user6.Password);

<span class="hljs-keyword">if</span> (facebookAuth)
    Console.WriteLine(<span class="hljs-string">$"New account registered with facebook: <span class="hljs-subst">{user6.UserName}</span>."</span>);

<span class="hljs-comment">/*
Output: New account registered with facebook: joerogan.
*/</span>
</code></pre>
<p>The <code>CallingCode</code> class depends on the abstraction provided by the interface (<code>IAuthWithFacebook</code>). It doesn't have direct knowledge of the concrete implementation (<code>AuthWithFacebook</code>), promoting decoupling between components. Hence, I will create a variable <code>authWithFacebookObj</code> assigning it as concrete implementation (higher module). This is know as dependency injection (you have a class that take interface as an parameter and you provide its concrete implementation at runtime or compile time).</p>
<h3 id="heading-takeaway-from-dependency-inversion-principle">Takeaway from Dependency Inversion Principle</h3>
<p>The Dependency Inversion Principle states decoupling high-level modules (interfaces) from low-level modules (implementations) by introducing abstractions (such as interfaces or abstract classes) that define the interactions between them. By depending on abstractions rather than concrete implementations, software design become more flexible, extensible, and easier to maintain.</p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p><strong>Single Responsibility Principle</strong>:</p>
<ul>
<li><p>Each unit of code (class, method, function) should have a single responsibility.</p>
</li>
<li><p>Promotes easier debugging and maintainability.</p>
</li>
<li><p>Example: Separate validation, registration, and email confirmation in an authentication module.</p>
</li>
</ul>
</li>
<li><p><strong>Open/Closed Principle</strong>:</p>
<ul>
<li><p>Software entities should be open for extension but closed for modification.</p>
</li>
<li><p>Encourages adding new functionalities without altering existing code.</p>
</li>
<li><p>Example: Extending authentication logic without modifying the original code.</p>
</li>
</ul>
</li>
<li><p><strong>Liskov Substitution Principle</strong>:</p>
<ul>
<li><p>Child classes should be exchangeable for their base (parent) classes.</p>
</li>
<li><p>Objects of a subclass should be able to replace objects of the superclass without affecting program correctness.</p>
</li>
<li><p>Encourages code reusability and extensibility.</p>
</li>
<li><p>Example: Extending authentication classes without changing their behavior.</p>
</li>
</ul>
</li>
<li><p><strong>Interface Segregation Principle</strong>:</p>
<ul>
<li><p>Interfaces should be tailored to specific objects and should not contain irrelevant functionalities.</p>
</li>
<li><p>Classes should only implement interfaces that are relevant to their functionality.</p>
</li>
<li><p>Promotes cleaner and more modular design.</p>
</li>
<li><p>Example: Defining separate interfaces for different authentication methods.</p>
</li>
</ul>
</li>
<li><p><strong>Dependency Inversion Principle</strong>:</p>
<ul>
<li><p>High-level modules should not depend on low-level modules. Both should depend on abstractions.</p>
</li>
<li><p>Abstractions should not depend on details; details should depend on abstractions.</p>
</li>
<li><p>Promotes decoupling, flexibility, and maintainability.</p>
</li>
<li><p>Example: Using interfaces to define interactions between modules and injecting concrete implementations at runtime or compile time.</p>
</li>
</ul>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/demonstrating_solid_principles">Sourcecode</a></p>
]]></content:encoded></item><item><title><![CDATA[async and await]]></title><description><![CDATA[In my previous post, I provided a brief intro to asynchrony. In this post, I will continue with TAP (Task-based Asynchronous Programming) which utilizes TPL (Task parallel library) and it is a standard pattern to achieve asynchrony in modern C#.
Intr...]]></description><link>https://sushantpant.com.np/async-and-await</link><guid isPermaLink="true">https://sushantpant.com.np/async-and-await</guid><category><![CDATA[asp.net core]]></category><category><![CDATA[C#]]></category><category><![CDATA[async/await]]></category><category><![CDATA[asynchronous programming]]></category><category><![CDATA[asynchrony]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Sat, 20 Jan 2024 16:15:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705756246975/f4b47d09-f802-4816-9c68-673fd46ccba8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my previous <a target="_blank" href="https://sushantpant.com.np/introduction-to-asynchrony">post</a>, I provided a brief intro to asynchrony. In this post, I will continue with TAP (Task-based Asynchronous Programming) which utilizes TPL (Task parallel library) and it is a standard pattern to achieve asynchrony in modern C#.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>In TAP(Task-based Asynchronous Programming), <code>async</code> <code>await</code> keyword and <code>Task</code> class does everything to achieve asynchronous behavior. Simply understanding, the <code>async</code> is used to say "this is my asynchronous method/function". But just highlighting a function with <code>async</code> keyword doesn't make it asynchronous. If the asynchronous operation which is being awaited by using <code>await</code> keyword has not yet completed, it will return immediately. <code>Task</code> is a common type that can be awaited. Synchronous flow like not executing next operation is still maintained in asynchronous operation but without blocking or pausing the thread. If the task is already in completed state, code flow will execute as usual.</p>
<p>When long running operation is being awaited, the compiler sets a continuation to be executed after the operation has completed. Meaning, execution will start from where it left after the awaited operation has completed. Continuation is a callback (delegate) that will be executed as soon as the awaited operation has completed. Simpler terms, continuation is just a piece of code to be executed when the awaited operation has completed. Continuations are <code>Action</code> delegate that receives result of the asynchronous operation (<code>Action&lt;Task&lt;TResult&gt;&gt;</code> or <code>Action&lt;Task&gt;</code>). The type of the awaited asynchronous operation is usually <code>Task</code> or <code>Task&lt;TResult&gt;</code>. You can obviously have your own custom awaitable types but .NET provide <code>ValueTask&lt;TResult&gt;</code> which is better than having your own custom type. Custom types for awaiting is not preferred due to potential compatibility and tooling issues.</p>
<p><code>Task</code> has a method called <code>ContinueWith</code> to attach continuations. Continuations are heavily used in event-based pattern (EAP). EAP pattern involves the use of events and callback methods to notify the completion of asynchronous task.</p>
<p>TAP (Task-based Asynchronous Programming) doesn't rely heavily on continuations like EAP. TAP uses <code>await</code> keyword which provides a way to pause or wait for the asynchronous task to complete without blocking the thread. You might be wondering "what exactly does it mean to block the thread". It means the situation where the execution of code is blocked. It cannot execute further. Basically, the thread where this execution is happening becomes unable to proceed with other tasks.</p>
<h2 id="heading-task-based-asynchronous-pattern">Task-based asynchronous pattern</h2>
<p>In TAP, asynchronous operation doesn't wait for the task to complete. It starts and returns immediately. But what does it return?. It returns a sort of token. After initiating the asynchronous operation and obtaining the "token" (usually a <code>Task</code> or <code>Task&lt;TResult&gt;</code>), the execution of the calling code continues immediately. The "token" (<code>Task</code> or <code>Task&lt;TResult&gt;</code>) is used for coordination. What I mean by that is when you await a task, further execution is paused which allows asynchronous operation to finish before moving on to next step of code. You can await the task, register continuations, or perform any other operations based on the completion status of the asynchronous operation. Here's a simple example to visualize an async method:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">PrintSomethingAsync</span>(<span class="hljs-params"></span>)</span>
{
    Console.WriteLine(<span class="hljs-string">"Before awaiting."</span>);
    <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">2000</span>); <span class="hljs-comment">// simulating time consuming operation. </span>
    Console.WriteLine(<span class="hljs-string">"After awaiting"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">"returned val from async method."</span>;
}
</code></pre>
<p>Until the code reaches <code>await</code> keyword, it runs synchronously. After that, it starts an asynchronous operation which delays for 2 seconds simulating some computation. After waiting for 2 seconds, it prints and finally returns to the caller.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">string</span> ret = <span class="hljs-keyword">await</span> eg.PrintSomethingAsync();
Console.WriteLine(<span class="hljs-string">$"Returned from async method: <span class="hljs-subst">{ret}</span>"</span>);
Console.WriteLine(<span class="hljs-string">"All done."</span>);
</code></pre>
<p>Output:</p>
<pre><code class="lang-xml">Before awaiting.
After awaiting
Returned from async method: returned val from async method.
All done.
</code></pre>
<p>When you <code>await</code> an asynchronous operation (represented by a <code>Task</code> or <code>Task&lt;TResult&gt;</code>), it pauses the execution of the method at that point. However, it doesn't block the calling thread. Instead, it allows the calling thread to do other work while waiting for the asynchronous operation to complete. But if the <code>await</code> waits for the operation to complete and also immediately returns to the caller, how does it know where to start when the task is completed? This is achieved through the continuation. The compiler generates code to capture the current context and create a continuation that gets executed when the awaited task completes.</p>
<h2 id="heading-task">Task</h2>
<p>Simply put, <code>Task</code> class represents an asynchronous operation. <code>Task</code> encapsulates the ongoing or completed asynchronous operation. <code>Task</code> class provides varieties of methods to work with asynchronous operation. Some common methods are:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Method</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><code>Task.Start</code></td><td>Starts the task for the execution.</td></tr>
<tr>
<td><code>Task.Delay</code></td><td>Delays the task by passed parameter.</td></tr>
<tr>
<td><code>Task.Wait</code></td><td>Blocks the calling thread until the task completes.</td></tr>
<tr>
<td><code>Task.WaitAll</code></td><td>Wait until all tasks completes. Blocks all the calling thread.</td></tr>
<tr>
<td><code>Task.WaitAny</code></td><td>Wait until any of tasks completes. Blocks all the calling thread until any of the task completes.</td></tr>
<tr>
<td><code>Task.ContinueWith</code></td><td>Attach a continuation to the task.</td></tr>
<tr>
<td><code>Task.WhenAll</code></td><td>Basically saying "do this when all the task has completed".</td></tr>
<tr>
<td><code>Task.WhenAny</code></td><td>Basically saying "do this when any of the task completes".</td></tr>
<tr>
<td><code>Task.FromResult</code></td><td>Creates a task with the completed specified result.</td></tr>
<tr>
<td><code>Task.FromCancelled</code></td><td>Creates a canceled task with the specified cancellation token.</td></tr>
<tr>
<td><code>Task.FromException</code></td><td>Creates a faulted task with the specified exception</td></tr>
<tr>
<td><code>Task.IsCanceled</code></td><td>Gets whether the task has been canceled.</td></tr>
<tr>
<td><code>Task.IsFaulted</code></td><td>Gets whether the task has been faulted.</td></tr>
<tr>
<td><code>Task.IsCompleted</code></td><td>Gets whether the task has been completed.</td></tr>
<tr>
<td><code>Task.ConfigureAwait</code></td><td>Configure how continuations to be scheduled. Basically it is used to specify if you want your execution after continuation to continue in same thread (if <code>true</code>) or execute on a ThreadPool thread (if <code>false</code>).</td></tr>
<tr>
<td><code>Task.Factory</code></td><td>Access to <code>Task</code> class's factory methods.</td></tr>
<tr>
<td><code>Task.Status</code></td><td>Current status of the task.</td></tr>
</tbody>
</table>
</div><p><code>Task</code> has a <code>Status</code> property (<code>TaskStatus</code> enum) which holds the current state of the operation. <code>Task.Status</code> can be <code>Running</code>, <code>WaitingToRun</code>, <code>WaitingForActivation</code>, <code>RanToCompletion</code>, <code>Faulted</code>, <code>WaitingForChildrenToComplete</code> and <code>Canceled</code>.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Task Status</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><code>Created</code> : 0</td><td>The <code>Task</code> is initiated but not started or asynchronously waiting for completion.</td></tr>
<tr>
<td><code>WaitingForActivation</code> : 1</td><td>The <code>Task</code> is created but not yet scheduled for execution. (like: lazy loading of <a target="_blank" href="https://sushantpant.com.np/iterators-effortless-sequencing">iterator block</a>)</td></tr>
<tr>
<td><code>WaitingToRun</code> : 2</td><td>The <code>Task</code> is not executing, but scheduled for execution.</td></tr>
<tr>
<td><code>Running</code> : 3</td><td>The <code>Task</code> is currently executing its asynchronous operation.</td></tr>
<tr>
<td><code>WaitingForChildrenToComplete</code> : 4</td><td>The <code>Task</code> is completed but waiting for attached task to complete.</td></tr>
<tr>
<td><code>RanToCompletion</code> : 5</td><td>The <code>Task</code> is completed without any exceptions.</td></tr>
<tr>
<td><code>Canceled</code> : 6</td><td>The <code>Task</code> is canceled before it could complete its operation. (usage of cancellation token)</td></tr>
<tr>
<td><code>Faulted</code> : 7</td><td>The <code>Task</code> is completed due to an unhandled exceptions during execution.</td></tr>
</tbody>
</table>
</div><p>One more thing, <code>Task</code> doesn't need to be explicitly disposed. The management of <code>Task</code> instances is handled by the runtime and the GC (garbage collector).</p>
<p>When you await a <code>Task</code>, the compiler performs an unwrapping operation. This operation handles exceptions if <code>Task</code> is faulted, else extracts the result. The result type of the <code>await</code> expression is the type of the awaited task's result, which will be <code>TResult</code> for <code>Task&lt;TResult&gt;</code> or <code>void</code> for a plain <code>Task</code>. The result is not the original <code>Task</code> itself. Example:</p>
<pre><code class="lang-csharp">Task&lt;<span class="hljs-keyword">string</span>&gt; task = SomeHeavyTaskAsync();
<span class="hljs-keyword">string</span> result = <span class="hljs-keyword">await</span> task; <span class="hljs-comment">// unwraping operation converts Task&lt;string&gt; to string</span>
</code></pre>
<p>Here, I have a variable called <code>task</code> of type <code>Task&lt;string&gt;</code>. But when I <code>await</code>, it will unwrap from <code>Task&lt;string&gt;</code> to <code>string</code>.</p>
<h3 id="heading-exceptions-in-task-and-why-you-should-await-a-task">Exceptions in Task and why you should await a Task</h3>
<p>I previously said that awaiting a <code>Task</code> handles exceptions if faulted, else extracts the result. However, what if the task is not awaited? When the <code>Task</code> is not awaited, any exceptions that may have occurred during its execution may not be observed immediately. There may be multiple exceptions during this execution period. If not awaited, they will be stored but not thrown. This "stored" exception is called <code>AggregateException</code>. <code>AggregateException</code> is a wrapper that aggregates multiple exception. The main reason to not throw exception like synchronous flow is to prevent unhandled exceptions causing termination of the application. Also you don't want to hamper other <code>Task</code> when there is exception in some <code>Task</code> which is executing in parallel. Here is an example to demonstrate it.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">DemonstrateExceptionAsync</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">1000</span>); <span class="hljs-comment">// simulating some operation</span>
    Console.WriteLine(<span class="hljs-string">"after some operation."</span>);
    MethodWithExceptionAsync(); <span class="hljs-comment">// not awaiting</span>
    Console.WriteLine(<span class="hljs-string">"after exception in other task."</span>);
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(message:<span class="hljs-string">"exception inside the method."</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-string">"retured from DemonstrateExceptionAsync"</span>;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">MethodWithExceptionAsync</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">500</span>); <span class="hljs-comment">// simulating some operation</span>
    Console.WriteLine(<span class="hljs-string">"inside MethodWithExceptionAsync method."</span>);
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(message:<span class="hljs-string">"Exception outside the method."</span>);
}
</code></pre>
<p>Here, when <code>MethodWithExceptionAsync()</code> is initiated, it won't throw exception. Instead this exception is stored in <code>AggregateException</code>. Execution continues and reach another exception which will be stored in <code>AggregateException</code> too.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">var</span> exceptionMethod = eg.DemonstrateExceptionAsync();
<span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">1500</span>);
Console.WriteLine(<span class="hljs-string">"after initiating method with exception."</span>);
<span class="hljs-keyword">await</span> exceptionMethod;
Console.WriteLine(<span class="hljs-string">"after awaiting faulted task"</span>);
<span class="hljs-comment">/*
Output:
    after some operation.
    after exception in other task.
    after initiating method with exception.
    inside MethodWithExceptionAsync method.
-- Finally, throws an exception --
System.Exception: 'exception inside the method.'
*/</span>
</code></pre>
<p>In calling code, I didn't await the anonymous type variable <code>exceptionMethod</code> which is assigned to an async method <code>DemonstrateExceptionAsync()</code>. All exceptions that occurred within this method is stored in <code>AggregateException</code>. Unless I await an async method or if I try to access the result of an async method (<code>Task.Result</code>), there won't be any exception. So if I didn't do <code>await exceptionMethod;</code>, it won't throw an error.</p>
<p>It's important to understand that using <code>Task.Result</code> to get the result of an asynchronous operation can lead to deadlocks. Imagine a scene where you're waiting for a result using <code>Task.Result</code>, and the asynchronous operation needs a specific context, like the UI thread. If that context is blocked, a deadlock may occur, which hampers the operation. Output will be the following:</p>
<pre><code class="lang-xml">after some operation.
after exception in other task.
after initiating method with exception.
after awaiting faulted task
</code></pre>
<p>When I finally await this async method (<code>await exceptionMethod;</code>), the most recent exception of <code>AggregateException</code> is thrown which is <code>System.Exception: 'exception inside the method.'</code>.</p>
<p>Now I'm sure you know why awaiting a task is crucial. You don't want exception to be silent. Also awaiting a task ensures that the code after the <code>await</code> statement is executed only after the task has completed. This flow of execution is important to consider in asynchronous programming, preventing race conditions and ensuring expected order of execution.</p>
<blockquote>
<p><a target="_blank" href="https://stackoverflow.com/a/34550/13672836">race condition</a>: A race condition occurs when two or more threads can access shared data and they try to change it at the same time.</p>
</blockquote>
<h3 id="heading-cancelling-an-asynchronous-operation">Cancelling an asynchronous operation</h3>
<p>Cancellation in <code>Task</code> is supported via <code>CancellationToken</code>. This allows an asynchronous operation to cancel its operation. You can think of a real scenario like visiting a website. If that website is taking too long to load, you'll close that tab and reenter the url in new tab or probably reload the page. In such cases(reload, closing tab), browser(client) will send a cancellation token to the server to cancel the operation. This helps in resource utilization.</p>
<p>When an asynchronous operation is cancelled, its state becomes <code>Canceled</code>. To use cancellation in <code>Task</code>, you can pass <code>CancellationToken</code> which will be checked periodically. Example:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// asynchronous method which can be cancelled</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">DoSomethingWithCancellationAsync</span>(<span class="hljs-params">CancellationToken cts</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        Console.WriteLine(<span class="hljs-string">"Inside DoSomethingWithCancellationAsync method."</span>);
        <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">5000</span>, cts);
        Console.WriteLine(<span class="hljs-string">"Still inside DoSomethingWithCancellationAsync method, after long running operation."</span>);
    }
    <span class="hljs-keyword">catch</span>(OperationCanceledException oce)
    {
        Console.WriteLine(oce.Message);
    }
}
</code></pre>
<p>Here, <code>Task.Delay</code> method has a parameter that accepts cancellation token (<code>cts</code>) as an argument. This means that if the cancellation token is signaled before the delay completes, the operation will be canceled, and an <code>OperationCanceledException</code> will be thrown.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">using</span> (CancellationTokenSource cts = <span class="hljs-keyword">new</span> CancellationTokenSource())
{
    Task someTask = eg.DoSomethingWithCancellationAsync(cts.Token);  <span class="hljs-comment">// start the task</span>
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">2000</span>); <span class="hljs-comment">// delay further execution for 2 seconds</span>
        cts.Cancel(); <span class="hljs-comment">// cancel the operation after 2 seconds.</span>
        <span class="hljs-keyword">await</span> someTask;        
    }
    <span class="hljs-keyword">catch</span> (OperationCanceledException oce)
    {
        Console.WriteLine(<span class="hljs-string">$"Operation cancelled: <span class="hljs-subst">{oce.Message}</span>"</span>);
    }
}
<span class="hljs-comment">/*
Output:
    Inside DoSomethingWithCancellationAsync method.
    A task was canceled.
*/</span>
</code></pre>
<p>Here, <code>someTask</code> has already started the task. <code>someTask</code> will take 5 seconds to complete its operation. But I will cancel this operation in 2 seconds.</p>
<p>Now, what if we pass cancellation token after the operation has already completed? Well, cancellation token will have no effect. The asynchronous operation, once completed, cannot be canceled. Example:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">using</span> (CancellationTokenSource cts = <span class="hljs-keyword">new</span> CancellationTokenSource())
{
    Task someTask = eg.DoSomethingWithCancellationAsync(cts.Token);  <span class="hljs-comment">// start the task</span>
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">6000</span>); <span class="hljs-comment">// delay further execution for 6 seconds</span>
        cts.Cancel(); <span class="hljs-comment">// cancel the operation after 6 seconds.</span>
        <span class="hljs-keyword">await</span> someTask;        
    }
    <span class="hljs-keyword">catch</span> (OperationCanceledException oce)
    {
        Console.WriteLine(<span class="hljs-string">$"Operation cancelled: <span class="hljs-subst">{oce.Message}</span>"</span>);
    }
}
<span class="hljs-comment">/*
Output:
    Inside DoSomethingWithCancellationAsync method.
    Still inside DoSomethingWithCancellationAsync method, after long running operation
*/</span>
</code></pre>
<p>Here, <code>someTask</code> has already started the task. <code>someTask</code> will take 5 seconds to complete its operation. If I cancel this operation after 6 seconds, it won't cancel <code>someTask</code> because it has already completed having its state as <code>RanToCompletion</code>.</p>
<h2 id="heading-creating-an-asynchronous-method">Creating an asynchronous method</h2>
<p>Asynchronous methods can be generic, static, and can have any access modifiers. Creating an asynchronous method involves using the <code>async</code> keyword in the method signature, and the method should return either <code>Task</code> for void methods or <code>Task&lt;TResult&gt;</code> for methods with a result or <code>ValueTask&lt;TResult&gt;</code> or <a target="_blank" href="https://devblogs.microsoft.com/pfxteam/await-anything/">custom awaitable types.</a> Parameters for async methods are similar to regular methods, but <code>ref</code> and <code>out</code> are disallowed.</p>
<p><code>ref</code> and <code>out</code> are disallowed due to the complications of managing the state of these parameters across various asynchronous operation. Imagine a scenario where some async method is computing progress value (percentage). If <code>ref</code> and <code>out</code> were allowed, it would really be complex to work around. What if some referenced variable's value is modified in race condition?</p>
<h3 id="heading-asynchronous-anonymous-function">Asynchronous anonymous function</h3>
<p>Async <a target="_blank" href="https://sushantpant.com.np/captured-variables-lambda-expression-and-closures#heading-lambda-expression">anonymous function</a> are just unnamed lambda expression but are asynchronous. It allows for concise representation of asynchronous operations without the need to define a named method. To declare it, you use the <code>async</code> keyword just before a lambda expression.</p>
<p>Asynchronous lambda expression syntax: <code>async (parameter-list) =&gt; (expression-body)</code></p>
<p>This results in a concise way to represent a function with asynchronous operations. Example:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">DoSomethingWithAnonFuncAsync</span>(<span class="hljs-params"></span>)</span>
{
    Func&lt;Task&lt;<span class="hljs-keyword">string</span>&gt;, Task&lt;<span class="hljs-keyword">int</span>&gt;&gt; getStringLengthDelegateAsync = <span class="hljs-keyword">async</span> (str) =&gt;
    {
        <span class="hljs-keyword">string</span> task = <span class="hljs-keyword">await</span> str;  <span class="hljs-comment">// await parameter which is of type task</span>
        <span class="hljs-keyword">return</span> task.Length;
    };
    <span class="hljs-function"><span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">string</span>&gt; <span class="hljs-title">someStringLocalFuncAsync</span>(<span class="hljs-params"></span>) <span class="hljs-comment">// local function can be asynchronous as well</span></span>
    {
        <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">2000</span>); <span class="hljs-comment">// simulating some operation</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"something"</span>;
    }
    Task&lt;<span class="hljs-keyword">int</span>&gt; getLengthTask = getStringLengthDelegateAsync(someStringLocalFuncAsync());
    <span class="hljs-keyword">int</span> len = <span class="hljs-keyword">await</span> getLengthTask; <span class="hljs-comment">// unwrapping operation by await. Task&lt;int&gt; --&gt; int</span>
    Console.WriteLine(<span class="hljs-string">$"Length of string is: <span class="hljs-subst">{len}</span>"</span>);
}
</code></pre>
<p>This code might look a lot but let me break it down. Firstly, I created a delegate of type <code>Func&lt;Task&lt;string&gt;, Task&lt;int&gt;&gt;</code>. For implementation of this delegate, I created an anonymous async function which returns the length of the string passed(<code>str</code>). I awaited the passed string of <code>getStringLengthDelegateAsync</code> because it is asynchronous of <code>Task</code> type. <code>await</code> unwraps the result of <code>Task&lt;string&gt;</code> to <code>string</code>. Then return the length of that string. After that, you can see I created a local async function. Yes, local function can be asynchronous too. This local function named <code>someStringLocalFuncAsync</code> returns <code>Task&lt;string&gt;</code> after a 2 seconds delay.</p>
<p>Next, I created a variable of type <code>Task&lt;int&gt;</code> and assign it to the delegate. I passed a local function as an argument for this delegate because you can see that the return type of the local function <code>someStringLocalFuncAsync</code> and the parameter for the delegate <code>Func&lt;Task&lt;string&gt;, Task&lt;int&gt;&gt; getStringLengthDelegateAsync</code> are the same, i.e., <code>Task&lt;string&gt;</code>. After this, I await the <code>Task&lt;int&gt;</code> which unwraps the result as <code>int</code> and assign that to a integer variable. Finally, print that <code>int</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">await</span> eg.DoSomethingWithAnonFuncAsync();
<span class="hljs-comment">/*
Output:
    Length of string is: 9
*/</span>
</code></pre>
<h3 id="heading-success-or-failure-of-async-execution">Success or failure of async execution</h3>
<p>Awaited asynchronous have two possibilities. Either it has completed without any exception (<code>RanToCompletion</code>) or it has failed due to some exception (<code>Faulted</code>). When an async method waits for an asynchronous operation to complete, it really means the method is doing nothing. A continuation is attached to the operation and the method returns immediately. <code>SynchronizationContext</code> makes sure that the continuation executes in the right thread in GUI application.</p>
<blockquote>
<p><a target="_blank" href="https://stackoverflow.com/a/18098557/13672836">From stackoverflow:</a> Simply put, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx"><code>SynchronizationContext</code></a> represents a location "where" code might be executed. Delegates that are passed to its <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.send.aspx"><code>Send</code></a> or <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.post.aspx"><code>Post</code> method</a> will then be invoked in that location. (<code>Post</code> is the non-blocking / asynchronous version of <code>Send</code>)</p>
</blockquote>
<p>In Asp.Net Core, there is no dedicated UI thread. It makes sense to eliminate the dedicated UI thread in web APIs and web server scenarios. Asp.Net Core utilizes (TAP) task-based asynchronous pattern's async-await pattern to achieve asynchrony. Console application and background services utilizes thread pool. When an asynchronous operation completes in console app or background services, the continuation may run on a different thread from the one that initiated the operation. The thread pool efficiently manages these threads, preventing the application from being blocked.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Thread pool</td><td>UI thread</td></tr>
</thead>
<tbody>
<tr>
<td>Manage and provide workers threads.</td><td>Manage user interface in GUI applications.</td></tr>
<tr>
<td>Avoids the overhead of creating and destroying threads for each asynchronous operation.</td><td>Important for updating UI elements, handling user interactions, and maintaining a smooth user experience.</td></tr>
<tr>
<td>Threads from the pool are reused, leading to improved performance and resource utilization.</td><td><code>SynchronizationContext</code> ensures that asynchronous continuations execute in the correct UI thread context.</td></tr>
</tbody>
</table>
</div><h2 id="heading-await-does-it-all"><code>await</code> does it all</h2>
<p>When you <code>await</code> an asynchronous operation, the compiler pause the further execution until the operation completes. The compiler generates continuation to execute as soon as the operation completes and returns. If the awaited operation has not completed, it will return immediately. The calling code can continue with its execution, ensuring non-blocking behavior. If the environment is GUI, there is a <code>SynchronizationContext</code> which ensures that the continuation runs on the same UI thread. In context of Asp.Net core, where UI thread is not needed, continuations may run on a different thread (from ThreadPool).</p>
<p>If the awaited task completes with an exception, <code>await</code> handles it. If the task is faulted, it throws an exception. If it's canceled, it throws an <code>OperationCanceledException</code>. If the task completes successfully, it continues with the next line of code.</p>
<h3 id="heading-what-can-be-awaited">What can be awaited</h3>
<p>Any type that has a suitable methods or extension method can be awaited. Most common type that can be awaited is <code>Task</code>, <code>Task&lt;TResult&gt;</code>, <code>ValueTask&lt;TResult&gt;</code>, <code>IAsyncEnumerable&lt;T&gt;</code>, or any custom type which fulfills Task-Based Asynchronous Pattern can be awaited. Awaitable type must implement <code>System.Runtime.CompilerServices.INotifyCompletion</code> interface.</p>
<p>If we look at <code>Task&lt;TResult&gt;</code>, C# compiler looks for the following detail to be awaitable:</p>
<ol>
<li><p><code>GetAwaiter</code> method: The <code>Task&lt;TResult&gt;</code> type should have a parameterless method named <code>GetAwaiter</code> that only returns an awaiter object and cannot be void. For eg: <code>Task&lt;string&gt;</code> has such method like: <code>public TaskAwaiter&lt;string&gt; GetAwaiter();</code>. The return type of <code>GetAwaiter</code> method is called the awaiter type.</p>
</li>
<li><p>Awaitable types must implement <code>System.Runtime.CompilerServices.INotifyCompletion</code> interface. For eg: The <code>Task&lt;string&gt;</code> has such struct as <code>public struct TaskAwaiter&lt;string&gt; : INotifyCompletion</code>.</p>
</li>
<li><p>This awaiter type must have following property and method, respectfully:</p>
<ul>
<li><p><code>bool IsCompleted</code></p>
</li>
<li><p><code>void OnCompleted(Action&lt;TResult&gt;)</code></p>
</li>
</ul>
</li>
<li><p><code>IsCompleted</code> indicates whether the asynchronous operation has completed or not.</p>
</li>
<li><p><code>OnCompleted</code> receives <code>Action&lt;TResult&gt;</code> that will be executed once the awaited operation finishes or once <code>IsCompleted</code> is <code>true</code>.</p>
</li>
<li><p>Awaitable type must have <code>GetResult</code> method. <code>GetResult</code> is a non-generic parameterless method of the awaiter type (e.g., <code>TaskAwaiter&lt;TResult&gt;</code>). It retrieves the result of the awaited asynchronous operation. It is called when <code>IsCompleted</code> is <code>true</code>. Eg: <code>public TResult GetResult(){ ... }</code> for <code>TResult</code> or <code>public void GetResult()</code> for <code>Task</code> or <code>void</code>.</p>
</li>
<li><p><code>GetResult</code> method is also responsible for handling the result of the asynchronous operation. When the asynchronous operation has an exception, it will throw that exception to the caller. This is to make sure that any exceptions that occurred during the asynchronous operation are appropriately shown to the point where the asynchronous operation was awaited.</p>
</li>
</ol>
<h2 id="heading-full-codebase-goes-into-async-mode">Full codebase goes into async mode</h2>
<p>When there is an async method which has an asynchronous operation calling another async method and every operation is awaited, this creates a chain of asynchronous operations which ensures that the application remains responsive and efficient, handling tasks without blocking threads. Or in other word "the full codebase goes in async mode". That's how you achieve asynchrony.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">A</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> B();
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">B</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> C();
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">C</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> D();
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">D</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> E();
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">E</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> F();
}

<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">F</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">1000</span>);
}
</code></pre>
<p>Here, you can see a chain of asynchronous tasks where each task awaits the completion of the next one.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
<span class="hljs-keyword">var</span> someAsyncCodeTask = asyncMode.A();
<span class="hljs-keyword">await</span> someAsyncCodeTask;
Console.WriteLine(<span class="hljs-string">$"All async mode task completed. Status: <span class="hljs-subst">{someAsyncCodeTask.Status}</span>"</span>);
<span class="hljs-comment">/*
Output:
    All async mode task completed. Status: RanToCompletion
*/</span>
</code></pre>
<p>Here, call to <code>A</code> method would initiate a chain of an asynchronous operation. <code>A</code> is like the entry point. When you call <code>A</code>, it kicks off a sequence of tasks. <code>A</code> immediately says, "I'm going to wait for <code>B</code> to finish before I'm done." <code>B</code> is the second task. When <code>A</code> is waiting for <code>B</code>, it's like putting <code>B</code> on the to-do list and moving on to other things. <code>B</code> also says, "I'm going to wait for <code>C</code> to finish." <code>C</code> joins the chain. <code>A</code> is waiting for <code>B</code>, and <code>B</code> is waiting for <code>C</code>. <code>C</code> says, "I'll wait for <code>D</code> to finish." Same goes for Task <code>D</code> and <code>E</code>.</p>
<p>Finally, <code>F</code> is the last in line. <code>A</code>, <code>B</code>, <code>C</code>, <code>D</code>, and <code>E</code> are all waiting for <code>F</code>.</p>
<p>In summary, transitioning your codebase into async mode not only improves the efficiency and responsiveness of your application but also sets the foundation for scalable and performant software, especially in scenarios where parallel execution of tasks can significantly enhance overall system.</p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p>TAP uses <code>async</code> <code>await</code> keyword and the <code>Task</code> class to achieve asynchrony.</p>
</li>
<li><p><code>Task</code> class represents an asynchronous operations.</p>
</li>
<li><p>Async methods don't wait for completion; they start and return immediately.</p>
</li>
<li><p>Awaiting tasks handles exceptions immediately.</p>
</li>
<li><p>Avoid using <code>Task.Result</code> to prevent deadlocks.</p>
</li>
<li><p><code>CancellationToken</code> allows canceling asynchronous operations.</p>
</li>
<li><p><code>SynchronizationContext</code> manages the execution context, mostly in GUI applications where there is UI thread.</p>
</li>
<li><p>Asp.Net Core utilizes TAP to achieve asynchrony without a dedicated UI thread.</p>
</li>
<li><p>Async methods can be generic, static, and can have various access modifiers.</p>
</li>
<li><p><code>ref</code> and <code>out</code> parameters are disallowed for simplicity in state management.</p>
</li>
<li><p>Awaiting tasks can result in completion (<code>RanToCompletion</code>) or failure (<code>Faulted</code>).</p>
</li>
<li><p>Proper awaiting ensures expected execution order and prevents race conditions.</p>
</li>
<li><p>Common awaitable types include <code>Task</code>, <code>Task&lt;TResult&gt;</code>, <code>ValueTask</code>, and <code>IAsyncEnumerable</code>.</p>
</li>
<li><p>Any type with suitable methods or extension methods can be awaited.</p>
</li>
<li><p>Chaining async methods (asynchronous programming) creates a responsive and efficient application.</p>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/async_await_demo">Sourcecode</a></p>
<p>More on async await can be read at:</p>
<ul>
<li><p><a target="_blank" href="https://csharpindepth.com/">C# in depth</a> Fourth edition by Jon Skeet</p>
</li>
<li><p><a target="_blank" href="https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md">David Fowler's tips on best asynchronous programming practices</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=n6kiJKr4_oA">NDC conference: Efficient Async and Await</a> by Filip Ekberg</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Introduction to Asynchrony]]></title><description><![CDATA[Before continuing asynchrony, I would like mention some misconception about being "asynchronous". Being asynchronous doesn't mean multi-threading or doesn't have to be multi-threaded. Asynchronous operation is simply used to avoid blockage of the wor...]]></description><link>https://sushantpant.com.np/introduction-to-asynchrony</link><guid isPermaLink="true">https://sushantpant.com.np/introduction-to-asynchrony</guid><category><![CDATA[asynchrony]]></category><category><![CDATA[.NET]]></category><category><![CDATA[C#]]></category><category><![CDATA[asynchronous programming]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Mon, 15 Jan 2024 14:15:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704729497917/3a29ae75-f02d-4e2a-ad57-9defdd79ca18.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before continuing asynchrony, I would like mention some misconception about being "asynchronous". Being asynchronous doesn't mean multi-threading or doesn't have to be multi-threaded. Asynchronous operation is simply used to avoid blockage of the working thread without the need of additional threads. Another falsely statement, "asynchrony results faster execution". Effectiveness of asynchrony depends solely on the tasks involved. Typically In-Memory operations doesn't required to be asynchronous. Tasks such as read operation of an remote file or operation on database or requesting over the network can be beneficial by using asynchrony. On the other hand, a task that requires significant amount of time to complete should be awaited, in other words, it can be beneficial if it is asynchronous. Also, asynchrony does not mean concurrency. Concurrency refers to the execution of multiple tasks, but they don't necessarily have to happen at the same time. While asynchrony allows tasks to proceed independently, without waiting for each other, concurrency focuses on the effective management of multiple tasks, whether they occur simultaneously or not.</p>
<p>One final misconception I would like to mention is "Asynchrony means parallel execution". This is false. Parallelism means executing multiple tasks at the same time. While asynchrony does allow parallelism, not all asynchronous operations are parallel. Asynchronous operations allow tasks to proceed independently without waiting, it doesn't necessarily be simultaneous execution.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>Synchronous operation, or simply the normal flow of code, pauses the thread when the task or any computation is not yet completed. Computation can be any sort of thing like performing CRUD operation, or anything that requires some resource. During the pause session, the thread is waiting for the computation to finish and it cannot perform other tasks. Executing tasks without blocking the thread for the responsiveness of the application or APIs is said to be asynchrony. The difference between synchronous and asynchronous is that the asynchronous code waits for the operation to complete without blocking the current execution thread. Normal synchronous flow of code blocks the thread when there is some operation going, and it does this until the operation has completed.</p>
<h2 id="heading-a-bit-of-history-to-achieve-asynchrony-in-net">A bit of history to achieve Asynchrony in .NET</h2>
<p>Early version of .NET introduced <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm">Asynchronous Programming Model (APM)</a> to achieve asynchrony. APM used <code>IAsyncResult</code> to achieve asynchronous operation, it has all the functionality to achieve asynchronous operation. <code>IAsyncResult</code> provides properties to get information about the operation whether it has completed or not, the user state associated with the operation, and an asynchronous wait handle. To implement APM pattern, you would create two methods: <code>Begin</code> and <code>End</code>. <code>Begin</code> was used to initiate asynchronous operation with parameters such as callback delegate, the user state, any other required information. <code>Begin</code> returns <code>IAsyncResult</code> object. <code>End</code> was used as callback to retrieve the result of the operation. <code>End</code> takes <code>IAsyncResult</code> as a parameter which is returned by the <code>Begin</code> method.</p>
<p>As an evolution to APM pattern, .NET introduced <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-overview">Event-based Asynchronous pattern (EAP)</a>. Event-based Asynchronous pattern (EAP) is to notify when an operation completes by utilizing events and delegates. In EAP, the initiation of an asynchronous operation is performed by invoking a method suffixed with 'Async' such as <code>DoSomethingAsync</code>. Upon initiating the operation, an associated event, often named with a 'Completed' suffix, like <code>DoSomethingCompleted</code>, is triggered upon completion of <code>DoSomethingAsync</code>, signaling that the asynchronous task has finished. This event-driven approach allows to subscribe and handle the completion of events.</p>
<p>.NET 4.5 introduced <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap">Task-Based Asynchronous pattern (TAP)</a> by utilizing Task Parallel Library (TPL). TAP has become the standard pattern to achieve asynchrony in C#. <code>async</code> <code>await</code> keyword and <code>Task&lt;TResult&gt;</code> is used to achieve TAP. The <code>Task&lt;TResult&gt;</code> class is particularly powerful in TAP, allowing to perform asynchronous operations that produce a result. This result can be awaited using the <code>await</code> keyword, providing a clean way to handle asynchronous responses. <code>async</code> keyword is used to denote that the method is asynchronous.</p>
<h2 id="heading-showcasing-asynchrony">Showcasing asynchrony</h2>
<p>Here is an simple example to demonstrate the importance of asynchrony. I will create an desktop application using Windows Forms and add two buttons: <code>Non-Async Button</code> and <code>Async Button</code>. <code>Non-Async Button</code>'s click event will have a synchronous flow whereas <code>Async Button</code> will have an asynchronous flow. This example is based on TAP pattern. Here is the code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Non-async button event handler</span>
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">button1_Click</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> sender, EventArgs e</span>)</span>
{
    textBox1.Text = <span class="hljs-string">"Non-async button clicked. Pausing thread for 5 seconds..."</span>;
    Thread.Sleep(<span class="hljs-number">5000</span>); <span class="hljs-comment">// replicating time consuming operation.</span>
    textBox1.Text = <span class="hljs-string">"Non-async operation completed."</span>;
}
</code></pre>
<p>Before <code>Thread.Sleep(5000);</code>, the <code>textBox1</code> text field will also not be printed. It is due to the fact that the UI is not being updated during the <code>Thread.Sleep(5000)</code> operation because this operation is blocking the UI thread.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// async button event handler</span>
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> <span class="hljs-keyword">void</span> <span class="hljs-title">button2_Click</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> sender, EventArgs e</span>)</span>
{
    textBox2.Text = <span class="hljs-string">"Async button clicked. delaying task for 5 seconds without pausing thread."</span>;
    <span class="hljs-keyword">await</span> Task.Delay(<span class="hljs-number">5000</span>); <span class="hljs-comment">// replicating time consuming operation.</span>
    textBox2.Text = <span class="hljs-string">"Async operation completed."</span>;
}
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705072032882/68e834dc-95b8-4111-99fc-1f45e2ac714c.gif" alt class="image--center mx-auto" /></p>
<p>You can see that I can write text before pressing <code>Non-Async Button</code>. But when I clicked <code>Non-Async Button</code>, whole application freezes. I cannot write or highlight over the textfield. The <code>Thread.Sleep(5000)</code> in the <code>button1_Click</code> (Non-async button) method is being executed on the UI thread, causing the entire UI to freeze during that period (5 seconds). In GUI application like Windows forms, the UI thread is responsible for handling inputs, updating UI and responding to events. When a time-consuming operation is performed on the UI thread, such as using <code>Thread.Sleep</code>, it freezes the entire UI because the thread is occupied with that operation and cannot perform its other duties.</p>
<p>But when I used <code>async/await</code> pattern, there is no pause and thread blockage. The <code>await Task.Delay(5000)</code> line represents an asynchronous delay of 5 seconds. During this period, the UI thread is not paused, and it can handle other tasks, respond to the user input, and update the UI as needed. Actually the code runs synchronously till <code>await</code>. As soon as it reaches <code>await</code>, it doesn't matter if the operation has completed or not, it will return. This is the power of the <code>async/await</code> pattern. When the code reaches the <code>await</code> keyword, it essentially says, "I'm going to pause here, but don't wait for me. Continue with other tasks you have to do, and when I'm ready, come back to this point." But how did the code ensure to update appropriate UI when something is awaiting? It does so by using <code>SynchronizationContext</code> class.</p>
<p>A continuation is created when the code reaches <code>await</code>. Continuation is basically a callback delegate that will be executed as soon as the awaited operation has completed. I will provide a detailed explanations on this topic in my upcoming blog post. Asynchronous operation is very crucial when responsiveness and non-blocking execution is your priorities.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this post, we get a touch of asynchronous and some history of asynchrony in .NET. Next post, I will cover the async/await pattern, the significance of the await keyword, and insights into writing effective asynchronous code. Stay tuned.</p>
<p><a target="_blank" href="https://github.com/sushantpt/Introduction_to_Asynchrony">Sourcecode</a></p>
<p><a target="_blank" href="https://blog.stephencleary.com/2013/11/there-is-no-thread.html">Stephen Cleary's blog post on asynchronous operation has no thread.</a></p>
]]></content:encoded></item><item><title><![CDATA[Captured variables]]></title><description><![CDATA[Introduction

variable : a symbolic name associated with a value and whose associated value may be changed - Wikipedia

Variables are like placeholders tied to values. They are entities that can be captured, moved around, and tweaked. Taking about ca...]]></description><link>https://sushantpant.com.np/captured-variables-lambda-expression-and-closures</link><guid isPermaLink="true">https://sushantpant.com.np/captured-variables-lambda-expression-and-closures</guid><category><![CDATA[capturedvariables]]></category><category><![CDATA[captured variable]]></category><category><![CDATA[Lambda Expression]]></category><category><![CDATA[closure]]></category><category><![CDATA[anonymous function]]></category><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><category><![CDATA[delegate]]></category><category><![CDATA[Functional Programming]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Tue, 02 Jan 2024 18:00:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704211379564/c8e1b673-7d18-4c11-b70c-4946e4ad1814.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<blockquote>
<p><strong>variable :</strong> a symbolic name associated with a value and whose associated value may be changed - <a target="_blank" href="https://en.wikipedia.org/wiki/Variable">Wikipedia</a></p>
</blockquote>
<p>Variables are like placeholders tied to values. They are entities that can be captured, moved around, and tweaked. Taking about captured variable, they refer to the instances where a variable defined in one scope is accessed and utilized in a different scope, typically in a lambda expression. Before digging deep into captured variables, let's understand lambda expression.</p>
<h2 id="heading-lambda-expression">Lambda Expression</h2>
<p>Lambda expression were introduced in C# version 3.0. Lambda expression allows a compact way to quickly create a function without following the standard way of a full function declaration. Lambda expression are frequently called as anonymous function due to their ability to define inline and unnamed functions.</p>
<p>Lambda expression syntax: <code>(parameter-list) =&gt; (expression-body)</code></p>
<p>You can read this as a function that takes the <code>parameter-list</code> as a parameter and returns the result of the <code>expression-body</code>. <code>parameter-list</code> is similar to regular parameter of a function/method. It can be any data type or object. The <code>expression-body</code> is the code that gets executed when the lambda expression is called. It is the logic body of function similar to method body. The difference is that the <code>expression-body</code> is inline. Lambda expressions are useful in scenarios where a short, scoped (one-time-use) function is needed. Here is a simple lambda expression which returns the sum of 2 numbers:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> Func&lt;<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>&gt; sumOf2Nums = (x, y) =&gt; x + y;
</code></pre>
<p>If we recall from my previous <a target="_blank" href="https://sushantpant.com.np/delegates-in-csharp#heading-the-versatile-funcltgt">article on delegates</a>, first two type parameters of above delegate <code>Func&lt;&gt; sumOf2Nums</code> takes 2 input parameter types(<code>int, int</code>), and the last <code>int</code> represents the return type. Then, we have a lambda expression <code>(x, y) =&gt; x + y;</code> which takes 2 <code>int</code> parameters which returns its sum. We can call this delegate like any other method/function:</p>
<pre><code class="lang-csharp">sumOf2Nums(<span class="hljs-number">4</span>,<span class="hljs-number">8</span>);
</code></pre>
<p>When <code>sumOf2Nums(4,8)</code> is called, it invokes the anonymous function(lambda expression) with <code>x = 4</code> and <code>y = 8</code> which returns an <code>int</code> 12 which is the sum of <code>x</code> and <code>y</code>.</p>
<p>Now, let's write the similar method in standard way:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">sumOf2NumsRegularWay</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> x, <span class="hljs-keyword">int</span> y</span>)</span>
{
    <span class="hljs-keyword">return</span> x + y;
}
</code></pre>
<p>Both of our method (delegate and the standard way) returns same output but using lambda expression is slightly more concise. Lambda expression shines when you use extension method particularly working with sequences using LINQ. Here is an example:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// A delegate with lambda expression to get the total sum of a list.</span>
<span class="hljs-keyword">public</span> Func&lt;List&lt;<span class="hljs-keyword">int</span>&gt;, <span class="hljs-keyword">int</span>&gt; sumOfList = (listOfNums) =&gt; listOfNums.Sum();
</code></pre>
<pre><code class="lang-csharp">List&lt;<span class="hljs-keyword">int</span>&gt; someNumbers = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt; { <span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">9</span>, <span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>, <span class="hljs-number">11</span>, <span class="hljs-number">3</span>, <span class="hljs-number">16</span> };
<span class="hljs-keyword">int</span> sum = eg.sumOfList(someNumbers); <span class="hljs-comment">// invoke the delegate.</span>
Console.WriteLine(sum);
<span class="hljs-comment">// prints the sum of the list which is: 64</span>
</code></pre>
<p>We can do a lot of computation in the expression body of lambda expression. What if we want to get the sum of odd numbers that are less than 6? Here's how we can utilize other extension method:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// A delegate with lambda expression to get the total sum of odd numbers that are less than 6 a list.</span>
<span class="hljs-keyword">public</span> Func&lt;List&lt;<span class="hljs-keyword">int</span>&gt;, <span class="hljs-keyword">int</span>&gt; sumOfOddNums = (listOfNums) =&gt; listOfNums.Where(x =&gt; x &lt; <span class="hljs-number">6</span> &amp;&amp; x % <span class="hljs-number">2</span> != <span class="hljs-number">0</span>).Sum();
</code></pre>
<p><code>sumOfOddNums</code> expanded the usage of lambda expressions <code>(x =&gt; x &lt; 6 &amp;&amp; x % 2 != 0)</code> by implementing the LINQ extension <code>Where</code> method to filter odd numbers less than 6 before calculating their sum.</p>
<pre><code class="lang-csharp">List&lt;<span class="hljs-keyword">int</span>&gt; someNumbers = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt; { <span class="hljs-number">1</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">9</span>, <span class="hljs-number">4</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>, <span class="hljs-number">11</span>, <span class="hljs-number">3</span>, <span class="hljs-number">16</span> };
<span class="hljs-keyword">int</span> sumOfOddNums = eg.sumOfOddNums(someNumbers); <span class="hljs-comment">// invoke the delegate.</span>
Console.WriteLine(sumOfOddNums);    
<span class="hljs-comment">// prints the total sum of odd numbers which are less than 6 which is: {1,5,3} = 9</span>
</code></pre>
<p>It demonstrate how lambda expressions make it easy to express complex conditions in a clean and compact manner. Now rolling back to captured variables.</p>
<h2 id="heading-captured-variables">Captured variables</h2>
<p>When a variable defined in one scope is accessed and utilized in a different scope often within a lambda expression, it said to be captured variables. In simpler terms, any kind of variable that is declared outside of the lambda expression, but used within the lambda expression is said to be captured variable. It's important to note that the parameter of the lambda expression and variables declared within the lambda expression are not captured variables. Here's an example to demonstrate it:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> Action&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">IncrementCounterAction</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> incrementBy</span>)</span>
{
    <span class="hljs-keyword">int</span> defaultNumber = <span class="hljs-number">2</span>;
    Action&lt;<span class="hljs-keyword">int</span>&gt; action = input =&gt;
    {
        Console.WriteLine(<span class="hljs-string">$"Default counter value: <span class="hljs-subst">{defaultNumber}</span>"</span>);
        <span class="hljs-keyword">int</span> result = input + defaultNumber + incrementBy;
        Console.WriteLine(<span class="hljs-string">$"Increment action by (method argument): <span class="hljs-subst">{incrementBy}</span>"</span>);
        Console.WriteLine(<span class="hljs-string">$"Sum of method argument, lambda argument, and default local method value: <span class="hljs-subst">{result}</span>"</span>);
    };
    defaultNumber = <span class="hljs-number">10</span>; <span class="hljs-comment">// modify local variable</span>
    <span class="hljs-keyword">return</span> action;
}
</code></pre>
<p>In above code, <code>defaultNumber</code> and <code>incrementBy</code> is captured variable. Both of them is beyond the scope of <code>action()</code> delegate. To call this method:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// eg is the instance of a class</span>
Action&lt;<span class="hljs-keyword">int</span>&gt; action = eg.IncrementCounterAction(<span class="hljs-number">5</span>);
action(<span class="hljs-number">2</span>);
</code></pre>
<p>What do you think the output would be?</p>
<p>Output:</p>
<pre><code class="lang-xml">Default counter value: 10
Increment action by (method argument): 5
Sum of method argument, lambda argument, and default local method value: 17
</code></pre>
<p>This might be surprising. The reason behind this is <code>defaultNumber</code> being captured by reference. Lambda expression captures variable by their references. When you use a variable within a lambda expression, it captures the reference to that variable rather than its value. This means any changes made to the captured variable outside the lambda expression will be reflected inside the lambda, and vice versa. Capturing variables using reference allows lambda expression to have access to current state of variable in the surrounding scope and avoids creating unwanted copies of variables especially when lambdas are passed as parameter or used in asynchronous tasks.</p>
<p>Being unaware of this behavior can lead to unexpected results when variables are modified after the creation of lambda expression.</p>
<h2 id="heading-closures">Closures</h2>
<p>Closure is a mechanism that allows a lambda expression to capture and remember the variables and the environment in its lexical scope <code>{ }</code>, even if the lambda expression is executed outside that scope. Simply put, closures encapsulates variables and environment in which it was created, preserving both the variable and environment context. By environment, it is referring to the set of variables that are in scope and accessible at the time the closure is created. It ensures that the lambda expression keep a hold on its original surroundings, no matter when and where it is executed.</p>
<p>In our previous example, when the variable <code>defaultNumber</code> was captured in lambda expression, it formed a closure. This closure essentially locked onto the <code>defaultNumber</code> and its environment. So, when <code>defaultNumber</code> was modified outside the lambda expression, that change was also noticed and applied inside the lambda expression. Closures ensure that the lambda expressions have access to the current state of the variables in their surrounding scope.</p>
<p>Example:</p>
<p>Below, I'm creating a <code>CreateCounterAction()</code> method which returns an <code>Action</code> which essentially is a closure.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> Action <span class="hljs-title">CreateCounterAction</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">int</span> incrementBy = <span class="hljs-number">5</span>;
    <span class="hljs-comment">// here, action take empty parameter list.</span>
    Action action = () =&gt; 
    {
        incrementBy++;
        Console.WriteLine(<span class="hljs-string">$"Counter at: <span class="hljs-subst">{incrementBy}</span>"</span>);
    };
    <span class="hljs-keyword">return</span> action;
}
</code></pre>
<p>The closure in <code>action</code> captures the variable <code>incrementBy</code> which is outside of <code>action</code> lambda expression. In the <code>CreateCounterAction</code> method, the environment consists of the variable <code>incrementBy</code>. When the closure is formed, it encapsulates not only the variable itself but also the entire environment in which it exists meaning it holds onto the context in which it was created.</p>
<pre><code class="lang-xml">// calling code
Action closureAction = eg.CreateCounterAction();
closureAction();
closureAction();
closureAction();
closureAction();
</code></pre>
<p>When the <code>closureAction</code> is invoked, it increments the captured <code>incrementBy</code> and prints the value.</p>
<p>Output:</p>
<pre><code class="lang-xml">Counter at: 6
Counter at: 7
Counter at: 8
Counter at: 9
</code></pre>
<p>The closure here is like cache, it holds the state of the <code>incrementBy</code>. Each time you call <code>closureAction</code>, it recalls the previous value and continue.</p>
<p>Closures might get confusing due to the mechanism of how it capture variables. The confusion arises from the fact that closures capture variables by reference, not by value. In a loop, when a closure captures a variable, it doesn't store the current value of that variable at the time of creation. Instead it maintains a reference to the variable. Simply put, when the closure is executed, it looks up the current value of the variable in its original scope.</p>
<p>Example:</p>
<p>Below, I created a method that returns an array of <code>Action</code>. Firstly, I created an array of four actions. Each action is a closure capturing the loop variable <code>i</code>. When invoked, all closures print the final value of <code>i</code> after the loop. This happens because all the closures captured the variable <code>i</code> by reference, and when the closure(lambda expression) is actually invoked and not when they are created, they see the final value of <code>i</code> after the loop has completed resulting in an output of "4" for each invocation.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> Action[] <span class="hljs-title">ClosureActionInLoop</span>(<span class="hljs-params"></span>)</span>
{
    Action[] actions = <span class="hljs-keyword">new</span> Action[<span class="hljs-number">4</span>];
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">4</span>; i++)
    {
        actions[i] = () =&gt; Console.WriteLine(i);
    }
    <span class="hljs-keyword">return</span> actions;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
Action[] closureLoopActions = eg.ClosureActionInLoop();
<span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">var</span> loopAction <span class="hljs-keyword">in</span> closureLoopActions)
{
    loopAction();
}
</code></pre>
<p>Here, they all reference the same variable <code>i</code>, which has been updated to 4 by the end of the loop. Consequently, they all print the current value of this shared reference, resulting in "4" for each invocation.</p>
<p>Output:</p>
<pre><code class="lang-xml">4
4
4
4
</code></pre>
<p>To fix this, we can introduce local variable inside the loop. Fixed code:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> Action[] <span class="hljs-title">FixedClosureActionInLoop</span>(<span class="hljs-params"></span>)</span>
{
    Action[] actions = <span class="hljs-keyword">new</span> Action[<span class="hljs-number">4</span>];
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">4</span>; i++)
    {
        <span class="hljs-keyword">int</span> localVar = i; <span class="hljs-comment">// introduce local variable to let closure remember</span>
        actions[i] = () =&gt; Console.WriteLine(localVar);
    }
    <span class="hljs-keyword">return</span> actions;
}
</code></pre>
<p>By introducing <code>localVar</code>, each closure captures it own value, addressing the common issue of closures in loop.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// calling code</span>
Action[] fixedClosureLoopActions = eg.FixedClosureActionInLoop();
<span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">var</span> loopAction <span class="hljs-keyword">in</span> fixedClosureLoopActions)
{
    loopAction();
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-xml">0
1
2
3
</code></pre>
<p>Each closures assigned to <code>actions[i]</code> captures this local variable <code>localVar</code>. Unlike the previous example where the closure captured the loop variable <code>i</code> by reference, now it captures the <code>localVar</code> by value at the time of its creation.</p>
<p>Outside of a loop, variables are often captured by reference, while inside a loop, introducing a local variable allows for capturing by value, ensuring each closure remembers its value.</p>
<h3 id="heading-closures-impact-on-memory">Closures impact on memory</h3>
<p>It is crucial to understand the potential impact on memory while using closures. Yes, closures offer flexibility but when there is a long-lived object, you must consider its impact on memory. For instance, if a closure captures a reference to a large dataset, it keeps the data in memory even when it's no longer needed. This results in unnecessary memory consumption impacting the performance.</p>
<p>Some tips on overcoming this issue is to limit the scope of captured variable ensuring they only encapsulate necessary resource.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Captured variables are entities shared across scopes. Lambda expression or anonymous function serve as a concise function to create instant short-lived function. These lambda expressions often form closures, encapsulating both variables and their lexical environment <code>{ }</code>(set of variables in a scope). Closures ensure that the lambda expression retain access to the external variable's state allowing flexibility and preservation.</p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p><strong>Lambda Expressions:</strong> Short, inline functions; e.g., <code>(x, y) =&gt; x + y</code> sums two numbers.</p>
</li>
<li><p><strong>Captured Variables:</strong> Extend scope by accessing external variables, crucial in lambda expressions for dynamic behavior. Illustrated in <code>IncrementCounterAction</code> method, showcasing capture of variables in a closure.</p>
</li>
<li><p><strong>Closures:</strong> Preserve variable states and environment, ensuring access to original surroundings even outside the lexical scope <code>{ }</code>. Shown in <code>CreateCounterAction</code> method, capturing variables to maintain context outside the method.</p>
</li>
<li><p><strong>Memory Impact:</strong> Closures, while flexible, can lead to unnecessary memory consumption; mitigate by limiting the scope of captured variables. Addressed with examples, warning about unnecessary memory use in closures and recommending limited scope for efficient resource use.</p>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/Understanding_CapturedVariables">Sourcecode.</a></p>
<p>More on closures:</p>
<ul>
<li><p><a target="_blank" href="https://martinfowler.com/dslCatalog/closure.html">Martin Fowler's Closure article</a></p>
</li>
<li><p><a target="_blank" href="https://csharpindepth.com/articles/Closures">Jon Skeet's C# in depth</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Delegates in C#]]></title><description><![CDATA[Introduction
Delegates in C# are like the instructions you give to different pieces of code, telling them what to do and how to work together. Delegates were introduced in C# to provide a flexible and powerful mechanism for implementing callback func...]]></description><link>https://sushantpant.com.np/delegates-in-csharp</link><guid isPermaLink="true">https://sushantpant.com.np/delegates-in-csharp</guid><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><category><![CDATA[delegate]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Tue, 26 Dec 2023 17:15:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703595583233/73d14ef5-43cc-46f1-9b38-552ef48a1afb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Delegates in C# are like the instructions you give to different pieces of code, telling them what to do and how to work together. Delegates were introduced in C# to provide a flexible and powerful mechanism for implementing callback functions, event handling, functional programming and for asynchronous programming.</p>
<h3 id="heading-use-cases">Use Cases</h3>
<ul>
<li><p><strong>Callback function</strong>: Invoke one piece of code after an event or after execution of some code.</p>
<p>  Eg: Imagine a weather app where you need to fetch real time weather data from 3rd party sources. Instead of freezing the entire application while waiting for data, initiating an asynchronous data retrieval process can be optimal. You provide a callback function (delegate) that processes the weather once it is fetched. This ensures that your application remains responsive, and the weather information is seamlessly integrated when available.</p>
</li>
<li><p><strong>Event handling</strong>: Communicate and respond to certain occurrences, specially in event driven architecture.</p>
<p>  Eg: You have two buttons in your weather app interface: one for Celsius and another for Fahrenheit. Each button is associated with a click event. When a user clicks the Celsius button, the Celsius button click event is triggered which shows the data in °C.</p>
</li>
<li><p><strong>Functional programming</strong>: Delegates allow passing of function or methods as parameter which is the main idea behind functional programming. Think of it like legos. Just like Lego pieces that can be interchanged and combined to create various structures, delegates enable the passing of functions or methods as parameters to other functions. This paradigm is the core principle of functional programming.</p>
</li>
<li><p><strong>Asynchronous programming</strong>: Delegates allow you to define callback methods that get invoked when an asynchronous task completes.</p>
<p>  Eg: Imagine you're uploading photos to the cloud. Without asynchronous help, you'd have to wait for each photo to be uploaded before doing anything else. Asynchronous operation helps your app to start sending photos and not wait around. So, you're free to use the app while all your pictures get uploaded to the cloud in the background.</p>
</li>
</ul>
<h3 id="heading-example">Example</h3>
<p>By using <code>delegate</code> keyword with return type, delegate name, and parameters, you declare a delegate. A simple example portraying use of delegate:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">delegate</span> <span class="hljs-keyword">int</span> <span class="hljs-title">Addition</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b</span>)</span>;
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-comment">// method that takes two numbers (a and b) and returns their sum.</span>
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> <span class="hljs-title">AddNumbers</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b</span>)</span>
{
    <span class="hljs-keyword">return</span> a + b;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OperateAddNumbers</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-comment">// create an instance of the Addition delegate and point it to the private AddNumbers method.</span>
    Addition addition = <span class="hljs-keyword">new</span> Addition(AddNumbers);
    <span class="hljs-comment">// invokes the delegate, calling the AddNumbers method with following arguments.</span>
    <span class="hljs-keyword">int</span> ret = addition(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>);
    Console.WriteLine(<span class="hljs-string">$"Result of addition: <span class="hljs-subst">{ret}</span>"</span>);
}
</code></pre>
<p>Delegates are like messengers that deliver your instructions to someone who knows how to perform a specific task. In this example, we declare a delegate named <code>Addition</code> that represents the idea of adding two numbers. The private method <code>AddNumbers</code> is the actual source which computes in this task. Now, when the public method <code>OperateAddNumbers</code> wants to add numbers, it creates a helpful messenger (delegate) named <code>addition</code> and tells it, 'Go to <code>AddNumbers</code>, and ask it to add 1 and 2.' The messenger delivers the request, and we get the result.</p>
<p>So, delegates simplify our code by acting as messengers between different parts of our program, making sure the right source handle specific tasks.</p>
<p>Another scenario, imagine you have a notification service that can send messages, and you have users who want to receive those messages. A messenger is the one who delivers news to everyone.</p>
<p>We will build a <code>NotificationService</code> class that consists of the delegate <code>NotificationHandler</code>, messenger to notify of type <code>NotificationHandler</code> and the message sender <code>SendNotification</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">NotificationService</span>
{
    <span class="hljs-comment">// Delegate handling notification</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">delegate</span> <span class="hljs-keyword">void</span> <span class="hljs-title">NotificationHandler</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>;

    <span class="hljs-comment">// "messenger" to notify</span>
    <span class="hljs-keyword">public</span> NotificationHandler Notify;

    <span class="hljs-comment">// send notification </span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendNotification</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        <span class="hljs-comment">// ensure that there are subscribers to send notification</span>
        <span class="hljs-keyword">if</span>(Notify != <span class="hljs-literal">null</span>)
        {
            Notify(message);
        }
    }
}
</code></pre>
<p>Above, we declare a special kind of helper named <code>NotificationHandler</code> (a delegate). It's like saying, "Hey, I'm creating a messenger that can carry messages." <code>Notify</code> is our messenger. It's the one who will deliver the messages. When the <code>SendNotification</code> method is called, it checks if there is a messenger (<code>Notify</code>). If yes, it tells the messenger to deliver the message. User receives the notification through the messenger who ensures that the message is sent to every subscribed user.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Class portraying subscriber.</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Subscriber</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Username { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-comment">// Imagine this as a smartphone, showing user notification.</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ReceiveNotification</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"New notification for you <span class="hljs-subst">{Username}</span>: <span class="hljs-subst">{message}</span>"</span>);
    }
}
</code></pre>
<p>Each <code>Subscriber</code> has a method <code>ReceiveNotification</code>, which is what happens when the messenger delivers a message. In this case, it shows the message on the console.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// create notification service</span>
NotificationService notificationService = <span class="hljs-keyword">new</span> NotificationService();
<span class="hljs-comment">// create subscribers using collection initializer</span>
List&lt;Subscriber&gt; listOfSubscriber = <span class="hljs-keyword">new</span> List&lt;Subscriber&gt;()
{
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Priti"</span>},
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Jon"</span>},
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Ram"</span>}
};

<span class="hljs-comment">// Subscribe Users to the Notification Service </span>
<span class="hljs-keyword">foreach</span> (Subscriber subscriber <span class="hljs-keyword">in</span> listOfSubscriber)
{
    notificationService.Notify += subscriber.ReceiveNotification;
}

<span class="hljs-comment">// random amount of voucher </span>
Random randAMount = <span class="hljs-keyword">new</span> Random();
<span class="hljs-keyword">int</span> discountAmount = randAMount.Next(<span class="hljs-number">10</span>, <span class="hljs-number">251</span>);

<span class="hljs-comment">// send notification to the subscribers who are subscribed. </span>
notificationService.SendNotification(<span class="hljs-string">$"Here's a voucher of Rs. <span class="hljs-subst">{discountAmount}</span>! Enjoyyyyyy."</span>);
</code></pre>
<p>Now, each time the <code>SendNotification</code> method is called, it generates a random discount amount and includes it in the notification message. Subscribers will receive notifications with different voucher amounts every single time. Each user in the <code>listOfSubscribers</code> is subscribed to the <code>Notify</code> event of the <code>NotificationService</code> , its like saying, "Hey, when there's a message, let me know, and here's what I'll do with it". When the <code>SendNotification</code> method is called, it triggers the <code>Notify</code> event, and each subscribed user's <code>ReceiveNotification</code> method is invoked, displaying the received message.</p>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1703582590003/05c3a93b-6567-4c80-9fba-4956fb44dd08.png" alt class="image--center mx-auto" /></p>
<p>In simple terms, the delegate (<code>NotificationHandler</code>) acts as a messenger between the <code>NotificationService</code> and the subscribers (<code>Subscriber</code>). It allows the service to notify all subscribers when there's something exciting happening, like sending a voucher. So, the delegate facilitates communication and ensures everyone who's interested gets the news.</p>
<p>Delegates are extensively useful when implementing Observer Design Pattern and in Event-Driven architecture where an object (in our example, <code>NotificationService</code>) needs to notify other objects (such as <code>Subscriber</code>) about changes or events.</p>
<h2 id="heading-built-in-delegates">Built-in delegates</h2>
<p>C# introduced built in delegates types <code>Func&lt;&gt;</code>, <code>Predicate&lt;&gt;</code>, and <code>Action&lt;&gt;</code> in version 2.0. Instead of writing delegates yourself, these built in delegate types can be more expressive way to work with delegates. <code>Func&lt;&gt;</code>, <code>Predicate&lt;&gt;</code>, and <code>Action&lt;&gt;</code> are of generic delegate type meaning they can be used with different types of parameter and return types. This makes them highly reusable in various scenarios reducing the need for custom delegate. It also seamlessly integrate with LINQ expressions, making it more expressive on collections.</p>
<blockquote>
<p>I often skip writing my own custom delegates. <code>Func&lt;&gt;</code>, <code>Predicate&lt;&gt;</code>, and <code>Action&lt;&gt;</code> are my preferences due to the versatility and readability.</p>
</blockquote>
<div class="hn-table">
<table>
<thead>
<tr>
<td></td><td><code>Func&lt;&gt;</code></td><td><code>Predicate&lt;&gt;</code></td><td><code>Action&lt;&gt;</code></td></tr>
</thead>
<tbody>
<tr>
<td><em>Purpose</em></td><td>Represents a method with parameters and a return type.</td><td>Represents a method that evaluates a condition.</td><td>Represents a method with parameters and no return.</td></tr>
<tr>
<td><em>Return type</em></td><td>Has a return type (can be any type, including void).</td><td>Always returns a boolean (true or false).</td><td>Does not have a return type (void).</td></tr>
<tr>
<td><em>Parameters</em></td><td>Can have zero or more input parameters.</td><td>Usually has one input parameter.</td><td>Can have zero or more input parameters.</td></tr>
<tr>
<td><em>Example</em></td><td><code>public Func&lt;int, int, string&gt; AddNumbersFunc = (a, b) =&gt; (a + b).ToString();</code></td><td><code>public Predicate&lt;int&gt; isEven = num =&gt; num % 2 == 0;</code></td><td><code>public Action&lt;int, int&gt; printSumOfNums = (a, b) =&gt; Console.WriteLine($"Sum : {a + b}");</code></td></tr>
<tr>
<td><em>Example call</em></td><td><code>Console.WriteLine(concatenateNumbers(1, 4)); // Output: 5</code></td><td><code>Console.WriteLine(isEven(2)); // Output: True</code></td><td><code>printSum(30, 20); // Output: Sum: 50</code></td></tr>
<tr>
<td><em>Use case</em></td><td>Mathematical calculations, and custom logic in LINQ queries, leveraging its versatility to define functions tailored to specific needs in a single line of code.</td><td>Filtering or testing conditions.</td><td>Performing an action without returning a value.</td></tr>
</tbody>
</table>
</div><h3 id="heading-the-versatile-funcltgt">The versatile: <code>Func&lt;&gt;</code></h3>
<p>The versatility of <code>Func&lt;&gt;</code> allows it to produce result based on the input parameter. It's a generic delegate type that can represent any method with parameters and a return type.</p>
<p><strong>Where to use</strong>: you want to get result after doing something.</p>
<p><strong>Example</strong>: You want to calculate the total price of items in a shopping cart.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> Func&lt;List&lt;<span class="hljs-keyword">int</span>&gt;, <span class="hljs-keyword">int</span>&gt; calculateTotalPriceInTheCart = items =&gt; items.Sum();
</code></pre>
<pre><code class="lang-csharp">List&lt;<span class="hljs-keyword">int</span>&gt; itemInCartPrices = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt; { <span class="hljs-number">210</span>, <span class="hljs-number">450</span>, <span class="hljs-number">1500</span>, <span class="hljs-number">2600</span> };
<span class="hljs-keyword">int</span> totalPrice = eg.calculateTotalPriceInTheCart(itemInCartPrices);
Console.WriteLine(totalPrice);
<span class="hljs-comment">// Prints: 4760</span>
</code></pre>
<h3 id="heading-conditional-crafter-predicateltgt">Conditional crafter: <code>Predicate&lt;&gt;</code></h3>
<p><code>Predicate&lt;&gt;</code> is perfect for scenarios where you need to evaluate a condition and return a boolean. <code>Predicate&lt;&gt;</code> can be used in filtering collections, conditional validation, removing elements, custom conditions in LINQ, event handling, conditional logic in algorithms, and testing conditions in unit testing, leveraging its true or false outcomes to express a wide range of conditions in a single line of code.</p>
<p><strong>Where to use</strong>: you want to check some condition.</p>
<p><strong>Example</strong>: You want to check if a customer is eligible for a discount based on their purchase amount. If the total amount exceed 1000, customer receives 10% discount.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> Predicate&lt;<span class="hljs-keyword">int</span>&gt; isEligibleForDiscount = purchaseAmount =&gt; purchaseAmount &gt; <span class="hljs-number">1000</span>;
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">bool</span> eligible = eg.isEligibleForDiscount(totalPrice); <span class="hljs-comment">// Result: True</span>
Console.WriteLine(<span class="hljs-string">$"Is eligible for discount: <span class="hljs-subst">{eligible}</span>"</span>);
<span class="hljs-keyword">if</span> (eligible)
{
    Console.WriteLine(<span class="hljs-string">$"Total price before discount: <span class="hljs-subst">{totalPrice}</span>"</span>);
    totalPrice = totalPrice - (<span class="hljs-keyword">int</span>)(<span class="hljs-number">0.1</span> * totalPrice); <span class="hljs-comment">// explicit casting. Implicit casting is not allowed from decimal to int.</span>
    Console.WriteLine(<span class="hljs-string">$"Total price after 10% discount: <span class="hljs-subst">{ totalPrice}</span>"</span>);
}
<span class="hljs-comment">/*
Prints:
Is eligible for discount: True
Total price before discount: 4760
Total price after 10% discount: 4284
*/</span>
</code></pre>
<h3 id="heading-the-silent-executor-actionltgt">The silent executor: <code>Action&lt;&gt;</code></h3>
<p><code>Action&lt;&gt;</code> is a go-to delegate when you need to represent a method that takes parameters but doesn't return anything (its a <code>void</code>). It focus on action rather than returning the values. <code>Action&lt;&gt;</code> can be used where the focus is on execution rather than computation.</p>
<p><strong>Where to use</strong>: focus is on some action rather than computation.</p>
<p><strong>Example</strong>: You want to log a confirmation message when a customer makes a purchase.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> Action&lt;<span class="hljs-keyword">string</span>&gt; logPurchaseConfirmationMessage = message =&gt; Console.WriteLine(<span class="hljs-string">$"Log: <span class="hljs-subst">{message}</span>"</span>);
</code></pre>
<pre><code class="lang-csharp">eg.logPurchaseConfirmationMessage(<span class="hljs-string">"Purchase confirmed for username12345."</span>);
<span class="hljs-comment">// Action: it prints the log message. </span>
<span class="hljs-comment">// Log: Purchase confirmed for username12345.</span>
</code></pre>
<h2 id="heading-multicast-delegate">Multicast delegate</h2>
<p>Up to this point, we understood that a delegate references to a method allowing for a level of abstraction and flexibility in function invocation.</p>
<p>Moving on, the concept of multicast delegate is its ability to point to and invoke multiple methods concurrently. Multicast delegate can maintain a list of methods and invoke them concurrently. Its declaration is similar to regular delegate. The difference is we keep adding methods to the delegate. Basically, multicast delegate is a collection with multiple references to methods allowing it to invoke all of them when triggered at the same time.</p>
<p>In our previous example, <code>Subscriber</code> had only one method to receive message <code>ReceiveNotification(string message)</code>. We will add another method here <code>ReceiveAnotherNotification(string message)</code>. Think of this like apps in your smartphone. You can have bunch of them installed. You can receive messages/notifications from all of them. In our case, we can have as much notification as our subscribers want but we will invoke both of them using multicast delegate. Here is the added method:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ReceiveAnotherNotification</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
{
    Console.WriteLine(<span class="hljs-string">$"New notification for you from other service <span class="hljs-subst">{Username}</span>: <span class="hljs-subst">{message}</span>"</span>);
}
</code></pre>
<p><code>Subscriber</code> class now look like this:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Subscriber</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Username { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ReceiveNotification</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"New notification for you <span class="hljs-subst">{Username}</span>: <span class="hljs-subst">{message}</span>"</span>);
    }

    <span class="hljs-comment">// newly added method to demonstrate multicast delegate</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ReceiveAnotherNotification</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"New notification for you from other service <span class="hljs-subst">{Username}</span>: <span class="hljs-subst">{message}</span>"</span>);
    }
}
</code></pre>
<p>Now, we will add <code>ReceiveAnotherNotification(string message)</code> to be included in our notify. <code>+=</code> is used to add event handlers (methods or delegates) to an event (notify), allowing multiple subscribers to respond to an event when it occurs.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// create notification service</span>
NotificationService notificationService = <span class="hljs-keyword">new</span> NotificationService();
<span class="hljs-comment">// create subscribers</span>
List&lt;Subscriber&gt; listOfSubscriber = <span class="hljs-keyword">new</span> List&lt;Subscriber&gt;()
{
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Priti"</span>},
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Jon"</span>},
    <span class="hljs-keyword">new</span> Subscriber(){ Username = <span class="hljs-string">"Ram"</span>}
};

<span class="hljs-comment">// Subscribe Users to the Notification Service </span>
<span class="hljs-keyword">foreach</span> (Subscriber subscriber <span class="hljs-keyword">in</span> listOfSubscriber)
{
    notificationService.Notify += subscriber.ReceiveNotification;
    <span class="hljs-comment">// add reference of another method to our Notify delegate.</span>
    notificationService.Notify += subscriber.ReceiveAnotherNotification;
    <span class="hljs-comment">// this is multicast delegate. </span>
}

<span class="hljs-comment">// random amount of voucher </span>
Random randAMount = <span class="hljs-keyword">new</span> Random();
<span class="hljs-keyword">int</span> discountAmount = randAMount.Next(<span class="hljs-number">10</span>, <span class="hljs-number">251</span>);

<span class="hljs-comment">// send notification to the subscribers who are subscribed. </span>
notificationService.SendNotification(<span class="hljs-string">$"Here's a voucher of Rs. <span class="hljs-subst">{discountAmount}</span>! Enjoyyyyyy."</span>);
</code></pre>
<p>Everything looks similar to above delegate example except in the <code>foreach</code> loop where we added reference of <code>ReceiveAnotherNotification</code> in our <code>Notify</code> a "messenger". Now, when the <code>SendNotification</code> method is called, the multicast delegate <code>Notify</code> invokes both the <code>ReceiveNotification</code> and <code>ReceiveAnotherNotification</code> methods for each subscriber. It's like receiving notifications from multiple services or apps on your smartphone. The power of multicast delegates shines in scenarios where you want to notify multiple methods or subscribers about an event concurrently, enhancing the flexibility and extensibility of your event-driven architecture.</p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p><strong>Delegate:</strong></p>
<ul>
<li>Delegates in C# act as messengers, providing a flexible and powerful mechanism for callback functions, event handling, functional programming, and asynchronous programming.</li>
</ul>
</li>
<li><p><strong>Use Cases:</strong></p>
<ul>
<li><p>Callback Function: Invoke code after an event or execution.</p>
</li>
<li><p>Event Handling: Communicate and respond to occurrences in event-driven architecture.</p>
</li>
<li><p>Functional Programming: Pass functions or methods as parameters.</p>
</li>
<li><p>Asynchronous Programming: Define callback methods for asynchronous tasks.</p>
</li>
</ul>
</li>
<li><p><strong>Example:</strong></p>
<ul>
<li><code>NotificationService</code> class and <code>Subscriber</code> class demonstrate delegates in action, facilitating communication between a service and subscribers.</li>
</ul>
</li>
<li><p><strong>Built-in Delegate Types:</strong></p>
<ul>
<li><p><code>Func&lt;&gt;</code>: Represents a method with parameters and a return type.</p>
</li>
<li><p><code>Predicate&lt;&gt;</code>: Represents a method that evaluates a condition (always returns boolean).</p>
</li>
<li><p><code>Action&lt;&gt;</code>: Represents a method with parameters and no return (its a <code>void</code>).</p>
</li>
</ul>
</li>
<li><p><code>Func&lt;&gt;</code> <strong>:</strong></p>
<ul>
<li><p>Used when you want to produce a result based on input parameters.</p>
</li>
<li><p>Example: Calculating the total price of items in a shopping cart.</p>
</li>
</ul>
</li>
<li><p><code>Predicate&lt;&gt;</code> <strong>:</strong></p>
<ul>
<li><p>Perfect for checking conditions and returning a boolean result.</p>
</li>
<li><p>Example: Checking if a customer is eligible for a discount based on purchase amount.</p>
</li>
</ul>
</li>
<li><p><code>Action&lt;&gt;</code> <strong>:</strong></p>
<ul>
<li><p>Used when the focus is on executing actions without returning values.</p>
</li>
<li><p>Example: Logging a confirmation message when a customer makes a purchase.</p>
</li>
</ul>
</li>
<li><p><strong>Multicast Delegates:</strong></p>
<ul>
<li><p>Extension of regular delegates, pointing to and invoking multiple methods concurrently.</p>
</li>
<li><p>Maintain a list of methods for simultaneous invocation.</p>
</li>
<li><p>Example: Sending notifications to subscribers using a multicast delegate in <code>NotificationService</code>.</p>
</li>
</ul>
</li>
<li><p><strong>More :</strong></p>
<ul>
<li><p>Delegates simplify code by acting as messengers between different parts of the program.</p>
</li>
<li><p><code>Func&lt;&gt;</code>, <code>Predicate&lt;&gt;</code>, and <code>Action&lt;&gt;</code> are built-in delegate types for added expressiveness and versatility.</p>
</li>
<li><p>Multicast delegates enhance flexibility and extensibility in event-driven architectures.</p>
</li>
<li><p>Multicast delegate can maintain a list of methods and invoke them concurrently.</p>
</li>
</ul>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/Understanding_Delegates">Sourcecode.</a></p>
]]></content:encoded></item><item><title><![CDATA[Iterators: Effortless sequencing]]></title><description><![CDATA[Imagine a library with lots of books, in a "C# term," a collection of books. You find yourself on a search for a specific book, navigating through numerous bookshelves. Finally, after some searching, you found it.
Now, consider an alternative scenari...]]></description><link>https://sushantpant.com.np/iterators-effortless-sequencing</link><guid isPermaLink="true">https://sushantpant.com.np/iterators-effortless-sequencing</guid><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><category><![CDATA[iterator]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Wed, 20 Dec 2023 15:17:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703085144791/8af13d5a-c472-4d21-aac2-46aa0192c982.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine a library with lots of books, in a "C# term," a collection of books. You find yourself on a search for a specific book, navigating through numerous bookshelves. Finally, after some searching, you found it.</p>
<p>Now, consider an alternative scenario, instead of looking for a book yourself, you could've asked the librarian. The librarian would hand you the exact book you're looking for. Iterators function much like this librarian. Instead of traversing through the entire collection of book, they promptly provide you with the exact book you seek. The librarian and iterator share a common trait, they give you something only when you ask for it. In above example, it was a book. You asked the librarian for that specific book, you got the book.</p>
<p>An iterator is a method that provides sequence or source for an enumeration using the <code>yield break;</code> or <code>yield return;</code> statement. And yes, it is necessary to use <code>yield</code> keyword to declare an iterator block. <code>yield return</code> statement produces a value and pauses the execution whereas <code>yield break</code> statement terminates the execution of the iterator method. Iterators can return one of the following types:</p>
<ul>
<li><p><em>IEnumerable</em></p>
</li>
<li><p><em>IEnumerable&lt;T&gt;</em></p>
</li>
<li><p><em>IEnumerator</em></p>
</li>
<li><p><em>IEnumerator&lt;T&gt;</em></p>
</li>
</ul>
<blockquote>
<p>where T can be any type parameter or regular type</p>
</blockquote>
<p>If the return type of iterator method is non-generic, the <code>yield</code> type is <code>object</code> whereas for generic, the yield type is the provided type parameter. Eg:</p>
<ul>
<li>Non-Generic Iterator method (return type is object) :</li>
</ul>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable <span class="hljs-title">NonGenericIteratorBlock</span>(<span class="hljs-params"></span>)</span> {
    <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-string">"hello from non-generic iterator block."</span>;
}
</code></pre>
<ul>
<li>Generic iterator method (return type is of type parameter, i.e. int) :</li>
</ul>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">GenericIteratorBlock</span>(<span class="hljs-params"></span>)</span> {
    <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-number">42</span>;
    <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-number">100</span>;
}
</code></pre>
<p>Iterators stops the execution in the following cases:</p>
<ul>
<li><p>Exception occurs within the iterator block</p>
</li>
<li><p>Reaches <code>yield return</code> statement which says it is ready to produce the value</p>
</li>
<li><p>Hits the <code>yield break</code> statement which signals end of the sequence, hence <code>MoveNext()</code> returns false</p>
</li>
<li><p>End of the method or the iterator block (<code>MoveNext()</code> returns false)</p>
</li>
</ul>
<p>Here is another simple iterator method that prints even numbers. It uses the <code>yield</code> keyword to generate even numbers on demand :</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> IEnumerable&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">GenerateEvenNumbers</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; ; i++)
    {
        <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> i * <span class="hljs-number">2</span>;
    }
}
</code></pre>
<p>The absence of condition in the <code>for</code> loop makes it an infinite. To get first 10 even numbers :</p>
<pre><code class="lang-csharp">Example example = <span class="hljs-keyword">new</span> Example(); <span class="hljs-comment">// Initialize class which contain iterator method</span>
IEnumerable&lt;<span class="hljs-keyword">int</span>&gt; evenNumbers = example.GenerateEvenNumbers();<span class="hljs-comment">// iterator method</span>
<span class="hljs-comment">// invoke iterator by taking first 10 </span>
Console.WriteLine(<span class="hljs-string">"Iterator block:"</span>);
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">int</span> evenNumber <span class="hljs-keyword">in</span> evenNumbers.Take(<span class="hljs-number">10</span>))
{
    Console.WriteLine(evenNumber);
}
</code></pre>
<p>The loop stops after processing 10 elements, demonstrating the lazy evaluation of the iterator. Output of this snippet:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702740410997/9d73933b-a3e6-40f7-8158-3fdbb23f9f14.png" alt /></p>
<p>It is totally possible to create a method with similar result without using <code>yield</code> or iterator block.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">GenerateEvenNumbersNonIterator</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> totalCount</span>)</span>
{
    List&lt;<span class="hljs-keyword">int</span>&gt; evenNumbers = <span class="hljs-keyword">new</span> List&lt;<span class="hljs-keyword">int</span>&gt;();
    <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">while</span> (evenNumbers.Count &lt; totalCount)
    {
        evenNumbers.Add(i);
        i += <span class="hljs-number">2</span>;
    }
    <span class="hljs-keyword">return</span> evenNumbers;
}
</code></pre>
<pre><code class="lang-csharp">Console.WriteLine(<span class="hljs-string">"Non-iterator block:"</span>);
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">int</span> evenNumber <span class="hljs-keyword">in</span> example.GenerateEvenNumbersNonIterator(<span class="hljs-number">10</span>))
{
    Console.WriteLine(evenNumber);
}
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702740437690/3e41838e-586d-40d0-96b3-675e2c821808.png" alt /></p>
<p>Though the end results may seem similar, the main difference is lazy evaluation. Before digging into lazy evaluation, let's look at IEnumerable and IEnumerator.</p>
<h2 id="heading-ienumerable">IEnumerable</h2>
<p>IEnumerable interface from <code>System.Collections</code> namespace enables a collection to be enumerated or sequenced over. In simpler terms, implementing IEnumerable allows you to iterate through the collection using a loop. IEnumerable is the base class for all non-generic collections that can be enumerated. It has a single method <code>GetEnumerator()</code> which returns an IEnumerator.</p>
<h2 id="heading-ienumerator">IEnumerator</h2>
<p>IEnumerator interface from <code>System.Collections</code> namespace is a standard mechanism used for iterating over a collection. It has methods and properties like <code>Current</code> (to get the current item or element), <code>MoveNext()</code> (advances to the next element), <code>Reset()</code> (resets the iterator block or sets enumerator to its initial value). Enumerator is used to read underlying data in the collection and is not designed for mutable(changing or modifying) operations.</p>
<h3 id="heading-ienumerableienumerator-relationship">IEnumerable/IEnumerator relationship</h3>
<p>Think of an IEnumerable as a playlist of music (collection of music) and IEnumerator as a music player. IEnumerable represents a collection of playlist that you can iterate over. IEnumerator as a music player, it keeps track of the current song in the playlist (collection). The music player is responsible for playing songs one at a time. IEnumerator keeps track of the current song in the playlist (collection) as you iterate over it. You can play or skip each song using a loop and the <code>MoveNext()</code> method respectively. It doesn't change the playlist at all. It only change the music player's current state.</p>
<p>You can have multiple playlists (collections of music). You can also have multiple music players (instances of IEnumerator), each playing its playlist independently. Moving the music player to the next song doesn't affect other music players or the playlists itself.</p>
<p>When you want to start playing through songs, you ask the playlist (IEnumerable) for a new music player (IEnumerator) with <code>IEnumerable.GetEnumerator()</code>. This new music player is set to play through the songs in the playlist. Now, you're in control, able to pause, skip, and enjoy the music. What's interesting is that these actions, like moving to the next song using <code>MoveNext()</code>, only impact the current state of your music player, not the original playlist.</p>
<h2 id="heading-lazy-evaluation">Lazy evaluation</h2>
<p>In context of iterator block, lazy evaluation is a mechanism where a sequence is delayed or paused until its value is actually needed. It avoids unnecessary computation until the result is required. With the <code>yield</code> keyword, the iterator provides values on demand and one at a time. So the entire collection is not generated and stored in memory upfront. Iterators can have the following pros :</p>
<ul>
<li><p><strong>Efficient memory usage</strong>: As I mentioned, the entire collection is not stored in memory upfront. Hence, storing only when it is required.</p>
</li>
<li><p><strong>Infinite sequence</strong>: Since the values are generated as needed, working with "infinite" sequence is feasibly practical.</p>
</li>
<li><p><strong>Performant</strong>: Iterator avoids unnecessary computation, resulting in improved performance. The difference can be measured when working with resource intensive computation or calculations.</p>
</li>
</ul>
<p>Here is a snippet to compute infinite even numbers:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// example is a instance of a class that has the iterator GenerateEvenNumbers()</span>
IEnumerable&lt;<span class="hljs-keyword">int</span>&gt; enumerable = example.GenerateEvenNumbers();
IEnumerator&lt;<span class="hljs-keyword">int</span>&gt; enumerator = enumerable.GetEnumerator();
<span class="hljs-keyword">while</span> (enumerator.MoveNext())
{
    <span class="hljs-keyword">int</span> val = enumerator.Current;
    Console.WriteLine(val);
}
 <span class="hljs-comment">// Ctrl + C to stop the execution.</span>
</code></pre>
<p>Here, we first created an enumerable of type <code>int</code> (<code>IEnumerable&lt;int&gt;</code>), serving as an iterator for generating even numbers. Then, we instantiated an enumerator for that enumerable using <code>GetEnumerator()</code>, which returns an enumerator of type <code>int</code>. This sets up the collection to be iterated over one element at a time, initializing the enumerator to its initial element. Following that, a <code>while</code> loop checks <code>enumerator.MoveNext()</code>. The <code>MoveNext()</code> method moves the enumerator to the next element in the sequence. If an element exists, it returns true; otherwise, it returns false. The loop continues as long as <code>MoveNext()</code> returns true. <code>enumerator.Current</code> is a property that retrieves the current element in the sequence indicated by the enumerator.</p>
<p>Let's recall again to execute this "infinite" iterator 10 times :</p>
<pre><code class="lang-csharp">IEnumerable&lt;<span class="hljs-keyword">int</span>&gt; enumerable = example.GenerateEvenNumbers();
<span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">int</span> val <span class="hljs-keyword">in</span> enumerable.Take(<span class="hljs-number">10</span>))
{
    Console.WriteLine(val);
}
</code></pre>
<p><code>enumerator.MoveNext()</code> returns true for the first 10 iterations of the loop. The <code>Take(10)</code> method ensures that the loop iterates only 10 times by limiting the number of elements taken from the infinite sequence.</p>
<h3 id="heading-working-mechanism-of-lazy-evaluation">Working mechanism of lazy evaluation</h3>
<p>In the above example, we have a iterator <code>GenerateEvenNumbers();</code> which is a <code>IEnumerable&lt;int&gt;</code>. Nothing happens right away when we call it. Execution happens when we call <code>MoveNext()</code> of <code>GenerateEvenNumbers()</code>'s IEnumerator. The cool part? It doesn't bother generating all the numbers at once. It only works when prompted. Call <code>MoveNext()</code>, get a number. Don't call it, and the iterator stays in sleep mode, not bothering with the rest of the sequence. When <code>MoveNext()</code> is called again, it continues from where it left. Enumerator keeps track of the execution state allowing it to seamlessly pick up from where it left off. It's like bookmark in the book.</p>
<p>Lazy evaluation is like asking for even numbers one at a time using <code>GenerateEvenNumbers()</code>. It doesn't bother showing all the numbers at once; only when you say "Show me more" with <code>MoveNext()</code>. It remembers where it left off, acting like a bookmark in a book, making it easy to continue when you want.</p>
<p>Being lazy enhances efficiency and resources utilization. Unlike other means, where all computations are performed upfront, lazy evaluation delays computation until the result is actually needed. In <code>GenerateEvenNumbers()</code>, it generates even numbers on-demand using <code>yield return</code>. Without lazy evaluation, attempting to generate an infinite sequence would result in a program trying to calculate an infinite number of values, which is not practical or feasible. Nature of lazy enables you to work with potentially infinite data structures in a way that is both efficient and effective.</p>
<h2 id="heading-using-linq-in-iterators">Using LINQ in Iterators</h2>
<p>LINQ operates seamlessly with iterators allowing you to manipulate and be expressive with large set data. Here is a simple example to print even numbers greater than 10 and less than 100.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> conditionalEvenNumbers = example.GenerateEvenNumbers().Where(x =&gt; x &gt; <span class="hljs-number">10</span> &amp; x &lt; <span class="hljs-number">100</span>);
<span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">int</span> val <span class="hljs-keyword">in</span> conditionalEvenNumbers)
{
    Console.WriteLine(val);
}
</code></pre>
<p>This snippet prints out even numbers greater than 10 and less than 100 but there's a catch. <code>GenerateEvenNumbers()</code> will never terminate because the sequence is infinite. <code>MoveNext()</code> is not called after 98 (which is the last element from the <code>where</code> clause). The <code>IEnumerator</code> keeps track of its internal state, including the position in the sequence, allowing you to seamlessly continue from where you left off. So, when you conditioned the sequence, the state of the collection is still preserved by <code>IEnumerator</code>. This state-preserving behavior is a fundamental characteristic of iterators and lazy evaluation.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> conditionalEvenNumbers = example.GenerateEvenNumbers().Where(x =&gt; x &gt; <span class="hljs-number">10</span> &amp; x &lt; <span class="hljs-number">100</span>);
<span class="hljs-keyword">foreach</span>(<span class="hljs-keyword">int</span> val <span class="hljs-keyword">in</span> conditionalEvenNumbers.Take(<span class="hljs-number">5</span>))
{
    Console.WriteLine(val);
}
</code></pre>
<p>Here, we take first 5 elements. This will only take 5 elements that are greater than 10 and less than 100. This ensures that the iterator terminates and doesn't run indefinitely.</p>
<p>When working with iterators, its crucial to handle errors to ensure robustness. Use <code>yield break;</code> to exit iterators. If you want to end the sequence when some condition is met, use <code>yield break;</code></p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p><strong>Iterator:</strong></p>
<ul>
<li><p>Method that provides sequence or source for an enumeration.</p>
</li>
<li><p>Implemented using <code>yield return</code> and <code>yield break</code> statements.</p>
</li>
<li><p>Requires the <code>yield</code> keyword in iterator blocks for lazy execution.</p>
</li>
</ul>
</li>
<li><p><strong>Return Types of Iterators:</strong></p>
<ul>
<li><p>Can return types such as <code>IEnumerable</code>, <code>IEnumerable&lt;T&gt;</code>, <code>IEnumerator</code>, or <code>IEnumerator&lt;T&gt;</code>.</p>
</li>
<li><p>The return type of non-generic iterators is <code>object</code>, while generic iterators return the specified type parameter.</p>
</li>
</ul>
</li>
<li><p><strong>Halting Execution:</strong></p>
<ul>
<li>Iterators pause execution in cases of exceptions, encountering <code>yield return</code>, reaching <code>yield break</code>, or reaching the end of the iterator block.</li>
</ul>
</li>
<li><p><strong>Lazy Evaluation:</strong></p>
<ul>
<li><p>Lazy evaluation is a key feature of iterators.</p>
</li>
<li><p>Mechanism where a sequence is delayed or paused until its value is actually needed.</p>
</li>
<li><p>Demonstrated by generating even numbers on demand with the <code>yield</code> keyword.</p>
</li>
<li><p>Non-iterator methods compute results upfront, in contrast to the lazy evaluation of iterators.</p>
</li>
</ul>
</li>
<li><p><strong>IEnumerable and IEnumerator Relationship:</strong></p>
<ul>
<li><code>IEnumerable</code> represents a collection, and <code>IEnumerator</code> moves through elements one at a time.</li>
</ul>
</li>
<li><p><strong>Efficient Resource Utilization:</strong></p>
<ul>
<li><p>Lazy evaluation enhances efficiency by avoiding unnecessary computation until the result is needed.</p>
</li>
<li><p>Enables working with potentially infinite data structures.</p>
</li>
</ul>
</li>
<li><p><strong>LINQ with Iterators:</strong></p>
<ul>
<li>LINQ operates seamlessly with iterators, allowing expressive manipulation of data.</li>
</ul>
</li>
<li><p><strong>Handling Errors in Iterators:</strong></p>
<ul>
<li><p>Using <code>yield break</code> to exit iterators when necessary.</p>
</li>
<li><p>Using <code>try-catch</code> properly ensures smooth runtime execution.</p>
</li>
</ul>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/Understanding_Iterators">Sourcecode.</a></p>
]]></content:encoded></item><item><title><![CDATA[Demystify Generics in C#]]></title><description><![CDATA[If you have a written couple hundred lines of code then you have probably used generics knowingly or unknowingly. The concept of generic is simple, a general-purpose block of code that can handle type during compile time. It was introduced in C# vers...]]></description><link>https://sushantpant.com.np/demystify-generics-in-csharp</link><guid isPermaLink="true">https://sushantpant.com.np/demystify-generics-in-csharp</guid><category><![CDATA[C#]]></category><category><![CDATA[.NET]]></category><category><![CDATA[generics]]></category><dc:creator><![CDATA[Sushant Pant]]></dc:creator><pubDate>Wed, 13 Dec 2023 15:01:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1702482321248/901e2910-dcbf-40b7-87c7-2f53b2b533e1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have a written couple hundred lines of code then you have probably used generics knowingly or unknowingly. The concept of generic is simple, a general-purpose block of code that can handle type during compile time. It was introduced in C# version 2.0 and was a major feature. Collections was the reason it was introduced. <code>List&lt;string&gt;</code>, <code>List&lt;int&gt;</code>, <code>List&lt;Dictionary&lt;key, value&gt;&gt;</code>, etc., might look familiar, well they are all generic collection types. Here is the <code>List&lt;T&gt;</code> class (decompiled) from the <code>System.Collections.Generic</code> namespace. Under the hood, <code>List&lt;T&gt;</code> is actually an dynamic array. The list is initially empty and has a capacity of zero. Upon adding the first element to the list the capacity is increased to DefaultCapacity, and then increased in multiples of two as required.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">List</span>&lt;<span class="hljs-title">T</span>&gt; : <span class="hljs-title">IList</span>&lt;<span class="hljs-title">T</span>&gt;, <span class="hljs-title">IList</span>, <span class="hljs-title">IReadOnlyList</span>&lt;<span class="hljs-title">T</span>&gt;
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> DefaultCapacity = <span class="hljs-number">4</span>;

    <span class="hljs-keyword">internal</span> T[] _items; 
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">int</span> _size; 
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">int</span> _version; 

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> T[] s_emptyArray = <span class="hljs-keyword">new</span> T[<span class="hljs-number">0</span>];

    <span class="hljs-comment">// Constructs a List. The list is initially empty and has a capacity</span>
    <span class="hljs-comment">// of zero. </span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">List</span>(<span class="hljs-params"></span>)</span>
    {
        _items = s_emptyArray;
    }

    <span class="hljs-comment">// Constructs a List with a given initial capacity. The list is</span>
    <span class="hljs-comment">// initially empty, but will have room for the given number of elements</span>
    <span class="hljs-comment">// before any reallocations are required.</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">List</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> capacity</span>)</span>
    {
        <span class="hljs-keyword">if</span> (capacity &lt; <span class="hljs-number">0</span>)
            ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);

        <span class="hljs-keyword">if</span> (capacity == <span class="hljs-number">0</span>)
            _items = s_emptyArray;
        <span class="hljs-keyword">else</span>
            _items = <span class="hljs-keyword">new</span> T[capacity];
    }

    <span class="hljs-comment">// Constructs a List, copying the contents of the given collection. The</span>
    <span class="hljs-comment">// size and capacity of the new list will both be equal to the size of the</span>
    <span class="hljs-comment">// given collection.</span>
    <span class="hljs-comment">//</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">List</span>(<span class="hljs-params">IEnumerable&lt;T&gt; collection</span>)</span>
    {
        <span class="hljs-keyword">if</span> (collection == <span class="hljs-literal">null</span>)
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);

        <span class="hljs-keyword">if</span> (collection <span class="hljs-keyword">is</span> ICollection&lt;T&gt; c)
        {
            <span class="hljs-keyword">int</span> count = c.Count;
            <span class="hljs-keyword">if</span> (count == <span class="hljs-number">0</span>)
            {
                _items = s_emptyArray;
            }
            <span class="hljs-keyword">else</span>
            {
                _items = <span class="hljs-keyword">new</span> T[count];
                c.CopyTo(_items, <span class="hljs-number">0</span>);
                _size = count;
            }
        }
        <span class="hljs-keyword">else</span>
        {
            _items = s_emptyArray;
            <span class="hljs-keyword">using</span> (IEnumerator&lt;T&gt; en = collection!.GetEnumerator())
            {
                <span class="hljs-keyword">while</span> (en.MoveNext())
                {
                    Add(en.Current);
                }
            }
        }
    }

    <span class="hljs-comment">// methods like: Add(T item), AddRange(IEnumerable&lt;T&gt; collection), </span>
    <span class="hljs-comment">// Insert(int index, T item), Remove(T item), RemoveAt(int index), </span>
    <span class="hljs-comment">// RemoveAll(Predicate&lt;T&gt; match), Count(), Contains(T item), ...</span>

}
</code></pre>
<p>So when a <code>List&lt;int&gt;</code> is initialized, the compiler is replacing all of <code>T</code> in <code>List&lt;T&gt;</code> class including all of its method with <code>int</code> of <code>List&lt;int&gt;</code>. The compiler automatically determines the type of the generic type parameter <code>T</code> in <code>List&lt;T&gt;</code>, a process often referred to as type inference. Type inference is done without explicit casting and providing type safety.</p>
<p>Now, it's time to craft our very own generic class. Imagine we have a ware house where we can store clothes and shoes. To start, we'll define a Cloth class.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cloth</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _type { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> ? _price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Cloth</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> type, <span class="hljs-keyword">int</span> price</span>)</span>
    {
       _type = type;
       _price = price;
    }
}
</code></pre>
<p>Following that, we'll define a Shoe class.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cloth</span> : <span class="hljs-title">IProductService</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _type { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span>? _price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Cloth</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> type, <span class="hljs-keyword">int</span> price</span>)</span>
    {
        _type = type;
        _price = price;
    }
}
</code></pre>
<p>Then, we'll create a versatile warehouse class capable of offering flexibility for various storage needs either for cloth or shoe.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt;
{
    <span class="hljs-keyword">private</span> List&lt;T&gt; _items;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Warehouse</span>(<span class="hljs-params"></span>)</span>
    {
        _items = <span class="hljs-keyword">new</span> List&lt;T&gt;();
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddItem</span>(<span class="hljs-params">T item</span>)</span>
    {
        _items.Add(item);
        Console.WriteLine(<span class="hljs-string">"Item added successfully."</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RemoveItem</span>(<span class="hljs-params">T item</span>)</span>
    {
        _items.Remove(item);
        Console.WriteLine(<span class="hljs-string">"Item removed."</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintTotalItems</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">int</span> itemsCount = _items.Count;
        Console.WriteLine(<span class="hljs-string">$"Total items in the ware house: <span class="hljs-subst">{itemsCount}</span>"</span>);
    }
}
</code></pre>
<p>Let's now get to the business. I would like to create a Warehouse to store Clothes. Before storing cloth in the warehouse, I need some clothes.</p>
<pre><code class="lang-csharp">Cloth shirt = <span class="hljs-keyword">new</span>(<span class="hljs-string">"denim jeans"</span>, <span class="hljs-number">600</span>);
Cloth jacket = <span class="hljs-keyword">new</span>(<span class="hljs-string">"leather"</span>, <span class="hljs-number">1200</span>);
Cloth sweater = <span class="hljs-keyword">new</span>(<span class="hljs-string">"woolen"</span>, <span class="hljs-number">1800</span>);
</code></pre>
<p>Now, a warehouse to store cloth.</p>
<pre><code class="lang-csharp">Warehouse&lt;Cloth&gt; clothesWareHouse = <span class="hljs-keyword">new</span>();
</code></pre>
<p>Store clothes in the warehouse.</p>
<pre><code class="lang-csharp">clothesWarehouse.AddItem(shirt);
clothesWarehouse.AddItem(jacket);
clothesWarehouse.AddItem(sweater);
</code></pre>
<p>Check status of the clothe warehouse. Then, remove an item from the warehouse.</p>
<pre><code class="lang-csharp">clothesWarehouse.PrintTotalItems();
Console.WriteLine(<span class="hljs-string">"-- Remove an item from the warehouse. --"</span>);
clothesWarehouse.RemoveItem(sweater);
clothesWarehouse.PrintTotalItems();
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478763484/9ae821ce-34ff-498e-8a8b-11ce904b8482.png" alt class="image--center mx-auto" /></p>
<p>Now, discover the true impact of Generics in action. Let's build a warehouse to store Shoes. Before storing, I need some shoes.</p>
<pre><code class="lang-csharp">Shoe highTop = <span class="hljs-keyword">new</span>(<span class="hljs-string">"converse"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">900</span>);
Shoe boot = <span class="hljs-keyword">new</span>(<span class="hljs-string">"gucci"</span>, <span class="hljs-number">43</span>, <span class="hljs-number">3400</span>);
Shoe lowTop = <span class="hljs-keyword">new</span>(<span class="hljs-string">"air max 90"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">4500</span>);
</code></pre>
<p>A warehouse to store them.</p>
<pre><code class="lang-csharp">Warehouse&lt;Shoe&gt; shoeWarehouse = <span class="hljs-keyword">new</span>();
</code></pre>
<p>Store shoes in the warehouse.</p>
<pre><code class="lang-csharp">shoeWarehouse.AddItem(highTop);
shoeWarehouse.AddItem(boot);
shoeWarehouse.AddItem(lowTop);
</code></pre>
<p>Check status of the shoe warehouse. Then, remove 2 items from the warehouse.</p>
<pre><code class="lang-csharp">shoeWarehouse.PrintTotalItems();
Console.WriteLine(<span class="hljs-string">"-- Remove 2 items from the warehouse. --"</span>);
shoeWarehouse.RemoveItem(highTop);
shoeWarehouse.RemoveItem(boot);
shoeWarehouse.PrintTotalItems();
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478780920/49732f99-ccc4-48a1-bcc5-cfa7392ee9dd.png" alt class="image--center mx-auto" /></p>
<p>We used the same Warehouse to store clothes and shoes. What did we achieve? Well, we didn't create a separate class for ware house. By using generics, we've created a versatile Warehouse class that can adapt to different types of items without the need for separate implementations for clothes and shoes.</p>
<p>We achieved:</p>
<ul>
<li><p><strong>Code re-usability</strong> : The Warehouse adapts to various item types, providing the freedom to store clothes, shoes, or any other compatible items without rewriting the code.</p>
</li>
<li><p><strong>Flexibility</strong> : The Warehouse can store different types of items like clothes, shoes, and any other compatible items without needing to change the code.</p>
</li>
<li><p><strong>Reduced redundancy</strong> : Generics cut out the need for repeating code across different classes, eliminating the necessity for duplicate code in separate classes for different types.</p>
</li>
<li><p><strong>Maintainability</strong> : Centralizing logic improves maintainability, enhancing the overall manageability of our code.</p>
</li>
</ul>
<h3 id="heading-type-constraints"><strong>Type Constraints</strong></h3>
<p>Here are some problems with our plain, non-restricted generic class. What if someone wants to store <code>string</code> in a warehouse like <code>Warehouse&lt;string&gt;</code> or any other type. Warehouse is specifically for a "Product" which might not make sense for a warehouse to store type other than "Product". By introducing type constraints to ensure that only items of the specified type ("Product" in our scenario) can be added to the warehouse. Type constraint enhance type safety and prevent such potential runtime errors. We will introduce an interface <em>IProductService,</em> which will be implemented by any "Product". Let's construct <em>IProductService</em> and add a method that display product details.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IProductService</span> 
{
   <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DisplayProductDetails</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<p>Implement <em>IProductService</em> in our product types.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cloth</span> : <span class="hljs-title">IProductService</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _type { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span>? _price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Cloth</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> type, <span class="hljs-keyword">int</span> price</span>)</span>
    {
       _type = type;
       _price = price;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayProductDetails</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"A cloth product of type:<span class="hljs-subst">{_type}</span>"</span>);
    }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shoe</span> : <span class="hljs-title">IProductService</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _brand { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> _size { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> ? _price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Shoe</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> brand, <span class="hljs-keyword">int</span> size, <span class="hljs-keyword">int</span>? price</span>)</span>
    {
        _brand = brand;
        _size = size;
        _price = price;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayProductDetails</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"A shoe product of brand: <span class="hljs-subst">{_brand}</span> and of size: <span class="hljs-subst">{_size}</span>"</span>);
    }
}
</code></pre>
<p>Now, to make Warehouse to store only "<code>Product</code>" type, we will introduce a type constraint in our <code>Warehouse&lt;T&gt;</code> generic class.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">IProductService</span>
{
    <span class="hljs-keyword">private</span> List&lt;T&gt; _items;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Warehouse</span>(<span class="hljs-params"></span>)</span>
    {
        _items = <span class="hljs-keyword">new</span> List&lt;T&gt;();
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddItem</span>(<span class="hljs-params">T item</span>)</span>
    {
        _items.Add(item);
        Console.WriteLine(<span class="hljs-string">"Item added successfully."</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RemoveItem</span>(<span class="hljs-params">T item</span>)</span>
    {
        _items.Remove(item);
        Console.WriteLine(<span class="hljs-string">"Item removed."</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">TotalItems</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">int</span> itemsCount = _items.Count;
        Console.WriteLine(<span class="hljs-string">$"Total items in the ware house: <span class="hljs-subst">{itemsCount}</span>"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayAllProductDetails</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">foreach</span>(T item <span class="hljs-keyword">in</span> _items)
        {
            item.DisplayProductDetails();
        }
    }
}
</code></pre>
<p>In <em>Warehouse</em> class with a type parameter <code>T</code>, we added <code>DisplayAllProductsDetails()</code> method to print product detail. The <code>where T : IProductService</code> constraint specifies that the generic type <code>T</code> must implement the <code>IProductService</code> interface. Warehouse cannot be accept type beside <em>IProductService.</em></p>
<p>Below, since the Cloth type implements IProductService, Warehouse can store them.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Create some clothes</span>
Cloth shirt = <span class="hljs-keyword">new</span>(<span class="hljs-string">"denim jeans"</span>, <span class="hljs-number">600</span>);
Cloth jacket = <span class="hljs-keyword">new</span>(<span class="hljs-string">"leather"</span>, <span class="hljs-number">1200</span>);
Cloth sweater = <span class="hljs-keyword">new</span>(<span class="hljs-string">"woolen"</span>, <span class="hljs-number">1800</span>);

<span class="hljs-comment">// create warehouse to store clothes</span>
Warehouse&lt;Cloth&gt; clothesWarehouse = <span class="hljs-keyword">new</span>();
clothesWarehouse.AddItem(shirt);
clothesWarehouse.AddItem(jacket);
clothesWarehouse.AddItem(sweater);
clothesWarehouse.TotalItems();
Console.WriteLine(<span class="hljs-string">"-- Remove an item from the warehouse. --"</span>);
clothesWarehouse.RemoveItem(sweater);
clothesWarehouse.TotalItems();
clothesWarehouse.DisplayAllProductDetails();
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478802441/69d3a87e-7242-41ee-a7fb-d10d9fcbb955.png" alt class="image--center mx-auto" /></p>
<p>If we try to store other than IProductService type in our generic Warehouse, we will get compile-time error. Let's look at this by creating a type of Person.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">People</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> Age { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">People</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> name, <span class="hljs-keyword">int</span> age</span>)</span>
    {
        Name = name;

        Age = age;
    }
}
</code></pre>
<p>If I try to create Warehouse to store <code>People</code> :</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478811493/e915f0da-2779-4a95-b537-ccab642abb90.png" alt class="image--center mx-auto" /></p>
<p>Type constraints ensure the allowance of only certain types, enhancing code safety by preventing inappropriate types from being used and catching potential errors at compile-time rather than runtime. In our case, the <code>IProductService</code> constraint in <code>Warehouse&lt;T&gt;</code> ensures that only <code>IProductService</code> types can be stored in our warehouse.</p>
<h3 id="heading-generic-methods">Generic methods</h3>
<p>In addition to generic classes, C# design teams also introduced generic methods. Generic methods offers a powerful way to write functions that work with a variety of data types without sacrificing type safety. They are commonly used in algorithms and collection manipulation functions, where the type of data being processed can vary. Let's dive into an example. We will create a class that will provide us basic services of accounting. We will add a specific method to check if the product is expensive or not.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AccountingService</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AccountingService</span>(<span class="hljs-params"></span>)</span> { }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> Method to return consumption percentage.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span><span class="hljs-doctag">&lt;/returns&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">GetConsumptionPercentage</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> totalItem, <span class="hljs-keyword">int</span> currentItem</span>)</span>
    {
        <span class="hljs-keyword">return</span> totalItem/currentItem * <span class="hljs-number">100</span>;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> Is expensive if more than 1000.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span><span class="hljs-doctag">&lt;/returns&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsProductExpensive</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">T product</span>) <span class="hljs-keyword">where</span> T : IProductService</span>
    {
        <span class="hljs-keyword">return</span> product.GetProductPrice() &gt; <span class="hljs-number">1000</span>;
    }
}
</code></pre>
<p>Here, <code>IsProductExpensive&lt;T&gt;(T product)</code> is an generic method that will return the product expensiveness. For sake of type safety, only <em>IProductService</em> type can be checked. I added <code>GetProductPrice()</code> in <em>IProductService.</em> So, each type that implements <em>IProductService</em> will have <code>GetProductPrice()</code>. <code>Cloth</code> and <code>Shoe</code> class will have a method, something like this:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">GetProductPrice</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">return</span> _price ?? <span class="hljs-number">0</span>;
}
</code></pre>
<p>Our generic method returns <code>bool</code>. Let's print if a particular cloth is expensive.</p>
<pre><code class="lang-csharp">Cloth sweater = <span class="hljs-keyword">new</span>(<span class="hljs-string">"woolen"</span>, <span class="hljs-number">1800</span>);
<span class="hljs-comment">// check if sweater is expensive. Our logic insists &gt; 1000 to be expensive.</span>
AccountingService accountingService = <span class="hljs-keyword">new</span> AccountingService();
<span class="hljs-keyword">var</span> isExpensive = accountingService.IsProductExpensive(sweater);
Console.WriteLine(<span class="hljs-string">$"Is product expensive:<span class="hljs-subst">{isExpensive}</span>"</span>);
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478824360/9b786169-161c-480e-809a-bc8defc0c342.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-more-generic-constraints">More generic constraints</h3>
<p>C# supports many generic constraints. Following are some of the type constraint:</p>
<ul>
<li><p>new() : The <code>new()</code> constraint in the <code>Warehouse&lt;T&gt;</code> class specifies that the generic type parameter <code>T</code> must have a public parameterless constructor. This means that you can create an instance of <code>T</code> without providing any constructor arguments. However, it doesn't restrict the use of types that have other constructors; it just ensures the existence of a parameterless constructor.</p>
<p>  Syntax to use <code>new()</code> constraint:</p>
<pre><code class="lang-csharp">  <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">new</span>()
  {
     <span class="hljs-comment">// methods</span>
  }
</code></pre>
</li>
</ul>
<p> Warehouse now can be used by only type that have parameterless constructor. If we recall our <code>Cloth.cs</code>, <code>Shoe.cs</code>, and <code>People.cs</code>, and want to initialize them, they all have public parameterized constructor. Hence, <code>Warehouse&lt;T&gt; where T : new()</code> cannot be used, we will get an compile-time error. They must be have public parameterless parameter. </p>
<ul>
<li><p>Interface <code>&lt;interface name&gt;</code> : Interface constraint ensures generic type parameter to be implemented by the provided interface. Our original Warehouse uses interface type constraint.</p>
<p>  Syntax to use interface type constraint:</p>
<pre><code class="lang-csharp">  <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">IProductService</span>
  {
     <span class="hljs-comment">// methods</span>
  }
</code></pre>
</li>
<li><p>Class name (<code>&lt;base class&gt;</code>) : The class name constraint, also known as the base class constraint, ensures that a generic type parameter must be derived from or be the provided class. Our original Warehouse uses interface type constraint.</p>
<p>  Syntax to use base class type constraint:</p>
<pre><code class="lang-csharp">  <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">SomeBaseClass</span>
  {
     <span class="hljs-comment">// methods</span>
  }
</code></pre>
</li>
<li><p>notnull : <code>notnull</code> constraint ensures the generic type parameter to be a non-nullable reference or value type.</p>
<p>  Syntax to use notnull type constraint:</p>
<pre><code class="lang-csharp">  <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">notnull</span>
  {
     <span class="hljs-comment">// methods</span>
  }
</code></pre>
</li>
</ul>
<h3 id="heading-generic-variance">Generic Variance</h3>
<p>Generic variance refers to the ability to use a more specific type than originally specified (covariance) or a less specific type than originally specified (contravariance).</p>
<h4 id="heading-covariance">Covariance</h4>
<p>Covariance allows you to use a more derived type than originally specified. For example, we can create a general Warehouse to store our product (both shoe and cloth). We can achieve this by initializing a <code>Warehouse&lt;IProductService&gt;</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// create shoe</span>
Shoe ggSneaker = <span class="hljs-keyword">new</span>(<span class="hljs-string">"gucci"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">4400</span>);
Shoe airMax = <span class="hljs-keyword">new</span>(<span class="hljs-string">"air max 90"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">4500</span>);
<span class="hljs-comment">// create cloth</span>
Cloth winterCloth = <span class="hljs-keyword">new</span>(<span class="hljs-string">"hoodie"</span>, <span class="hljs-number">5500</span>);
Cloth winterCloth1 = <span class="hljs-keyword">new</span>(<span class="hljs-string">"sweater"</span>, <span class="hljs-number">1400</span>);
<span class="hljs-comment">/* covariance example */</span>
Warehouse&lt;IProductService&gt; covarianceWarehouse = <span class="hljs-keyword">new</span>();
<span class="hljs-comment">// add cloth type </span>
covarianceWarehouse.AddItem(winterCloth);
covarianceWarehouse.AddItem(winterCloth1);
<span class="hljs-comment">// add shoe type</span>
covarianceWarehouse.AddItem(ggSneaker);
covarianceWarehouse.AddItem(airMax);
<span class="hljs-comment">// print total items of covariance ware house</span>
covarianceWarehouse.DisplayAllProductDetails();
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478840348/fef1eb89-63ce-413a-8664-522c15042513.png" alt class="image--center mx-auto" /></p>
<p>Covariance allows you to treat a <code>Warehouse&lt;Derived&gt;</code> as a <code>Warehouse&lt;Base&gt;</code>, where <code>Derived</code> is a type derived from <code>Base</code>. Here, <code>IProductService</code> serves as the common base interface for both <code>Cloth</code> and <code>Shoe</code>, allowing to use covariance. The <code>out</code> keyword is used to explicitly declare covariance when dealing with generic types in interfaces and delegates. It provides a way to communicate the intent of the generic parameter usage. We can modify our <em>IProductService</em> like so:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IProductService</span>&lt;<span class="hljs-keyword">out</span> <span class="hljs-title">T</span>&gt; 
{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DisplayProductDetails</span>(<span class="hljs-params"></span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">GetProductPrice</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<p>The <code>out</code> keyword indicates covariance for the generic type parameter <code>T</code> in interfaces or delegates. It allows the type parameter to be used as a more derived (specific) type than originally specified, providing flexibility in scenarios where a more specific type is expected. Now, we need to modify all our <em>IProductService</em> derived classes like so:</p>
<p><code>Shoe.cs</code></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shoe</span> : <span class="hljs-title">IProductService</span>&lt;<span class="hljs-title">object</span>&gt;
{
   <span class="hljs-comment">// methods and properties</span>
}
</code></pre>
<p><code>Cloth.cs</code></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cloth</span> : <span class="hljs-title">IProductService</span>&lt;<span class="hljs-title">object</span>&gt;
{
   <span class="hljs-comment">// methods and properties</span>
}
</code></pre>
<p><code>Warehouse.cs</code></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Warehouse</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">where</span> <span class="hljs-title">T</span> : <span class="hljs-title">IProductService</span>&lt;<span class="hljs-title">object</span>&gt;
{
   <span class="hljs-comment">// methods and properties</span>
}
</code></pre>
<p><code>Main method</code></p>
<pre><code class="lang-csharp"><span class="hljs-comment">// create shoe</span>
Shoe ggSneaker = <span class="hljs-keyword">new</span>(<span class="hljs-string">"gucci"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">4400</span>);
Shoe airMax = <span class="hljs-keyword">new</span>(<span class="hljs-string">"air max 90"</span>, <span class="hljs-number">42</span>, <span class="hljs-number">4500</span>);
<span class="hljs-comment">// create cloth</span>
Cloth winterCloth = <span class="hljs-keyword">new</span>(<span class="hljs-string">"hoodie"</span>, <span class="hljs-number">5500</span>);
Cloth winterCloth1 = <span class="hljs-keyword">new</span>(<span class="hljs-string">"sweater"</span>, <span class="hljs-number">1400</span>);
<span class="hljs-comment">/* covariance example */</span>
Warehouse&lt;IProductService&lt;<span class="hljs-keyword">object</span>&gt;&gt; covarianceWarehouse = <span class="hljs-keyword">new</span>(); <span class="hljs-comment">// using object as type argument</span>
<span class="hljs-comment">// add cloth type </span>
covarianceWarehouse.AddItem(winterCloth);
covarianceWarehouse.AddItem(winterCloth1);
<span class="hljs-comment">// add shoe type</span>
covarianceWarehouse.AddItem(ggSneaker);
covarianceWarehouse.AddItem(airMax);
<span class="hljs-comment">// print total items of covariance ware house</span>
covarianceWarehouse.DisplayAllProductDetails();
</code></pre>
<p>Output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478864664/48a14af0-f076-44fe-90d6-f3a6164e573b.png" alt class="image--center mx-auto" /></p>
<p>Using <code>object</code> as a type parameter can be a solution in some cases, but it comes with a trade-off. When you use <code>object</code> as the generic type parameter, you sacrifice type safety and lose the benefits of working with specific types. Using "object" doesn't check type, so errors are only discovered at runtime which is a headache when debugging. In our scenario, we want to create a <code>Warehouse</code> that can store various types of products (clothes and shoes), it might be more beneficial to create a non-generic interface. Hence, it is not compulsory to use <code>out</code> keyword to achieve covariance.</p>
<h4 id="heading-contravariance">Contravariance</h4>
<p>Contravariance allows you to use a more base type than originally specified. Contravariance is exactly on the flip side of covariance. For example, with contravariance, you can treat a <code>Warehouse&lt;Product&gt;</code> as a <code>Warehouse&lt;Shoe&gt;</code>. However, you can only add shoes to it, not clothes.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Contravariant use of Warehouse</span>
Warehouse&lt;Shoe&gt; contravariantWarehouse = <span class="hljs-keyword">new</span>();
contravariantWarehouse.AddItem(partyShoe);
contravariantWarehouse.AddItem(runningShoe);
<span class="hljs-comment">//contravariantWarehouse.AddItem(nightWear); // Compile time error</span>
contravariantWarehouse.DisplayAllProductDetails();
</code></pre>
<p>Here, we created an warehouse of type shoe. We cannot add other than shoe in <code>contravariantWarehouse</code>.</p>
<p><strong>Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1702478883776/e323faea-a6c8-4334-bd57-8ffa88336f35.png" alt class="image--center mx-auto" /></p>
<p>In this continuation, I've added the creation of a <code>Shoe</code> instance for <code>partyShoe</code>, <code>runningShoe</code>, and a <code>Cloth</code> instance for <code>nightWear</code>. As mentioned, attempting to add <code>nightWear</code> to <code>contravariantWarehouse</code> will result in a compile-time error since <code>contravariantWarehouse</code> is specifically typed to only accept <code>Shoe</code> instances.</p>
<p>Contravariance provides flexibility when dealing with generic types, allowing you to treat a more specific type as a more general type. This can be useful in scenarios where you want to handle a broader range of types while maintaining type safety.</p>
<h2 id="heading-summary">Summary</h2>
<ol>
<li><p><strong>Generics in C#:</strong></p>
<ul>
<li><p>Introduced in C# version 2.0 for handling types at compile time.</p>
</li>
<li><p>Used for creating general-purpose code that works with different types.</p>
</li>
<li><p>Commonly used in collections like List&lt;T&gt;, providing type safety and code reusability.</p>
</li>
</ul>
</li>
<li><p><strong>Generic Classes:</strong></p>
<ul>
<li><p>Example of a generic class: Warehouse&lt;T&gt; capable of storing various types of products.</p>
</li>
<li><p>Achieves code reusability, flexibility, reduced redundancy, and maintainability.</p>
</li>
<li><p>Compiler determines the type of the generic parameter during compilation.</p>
</li>
</ul>
</li>
<li><p><strong>Achievements of using generics:</strong></p>
<ul>
<li><p>Code reusability: Warehouse adapts to various item types.</p>
</li>
<li><p>Flexibility: Warehouse stores different types without code modification.</p>
</li>
<li><p>Reduced redundancy: Generics eliminate the need for duplicate code.</p>
</li>
<li><p>Maintainability: Centralized logic improves code manageability.</p>
</li>
</ul>
</li>
<li><p><strong>Type Constraints:</strong></p>
<ul>
<li><p>Introduced to enforce specific conditions on generic types.</p>
</li>
<li><p>Example: Using an interface constraint (IProductService) to ensure only specific types can be stored in the warehouse.</p>
</li>
</ul>
</li>
<li><p><strong>Generic Methods:</strong></p>
<ul>
<li><p>Allows writing functions that work with a variety of data types without sacrificing type safety.</p>
</li>
<li><p>Example: AccountingService with a generic method IsProductExpensive&lt;T&gt; using type constraints.</p>
</li>
</ul>
</li>
<li><p><strong>More Generic Constraints:</strong></p>
<ul>
<li><p>new() constraint ensures a public parameterless constructor.</p>
</li>
<li><p>Interface and base class constraints restrict types to those implementing a specific interface or derived from a base class.</p>
</li>
<li><p>notnull constraint ensures a non-nullable reference or value type.</p>
</li>
</ul>
</li>
<li><p><strong>Generic Variance:</strong></p>
<ul>
<li><p>Covariance allows using a more derived type than originally specified.</p>
</li>
<li><p>Contravariance allows using a more base type than originally specified.</p>
</li>
<li><p>Example: Using covariance in a Warehouse&lt;IProductService&gt; to store both shoes and clothes.</p>
</li>
</ul>
</li>
<li><p><strong>Conclusion:</strong></p>
<ul>
<li><p>Generics in C# provide a powerful mechanism for creating flexible and reusable code.</p>
</li>
<li><p>Type constraints enhance type safety and prevent inappropriate types at compile-time.</p>
</li>
<li><p>Generic variance (covariance and contravariance) allows more flexibility in handling types.</p>
</li>
</ul>
</li>
</ol>
<p><a target="_blank" href="https://github.com/sushantpt/generics_code">Sourcecode.</a></p>
]]></content:encoded></item></channel></rss>