{"id":1567,"date":"2023-04-15T18:02:00","date_gmt":"2023-04-15T11:02:00","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=1567"},"modified":"2023-05-13T14:46:15","modified_gmt":"2023-05-13T07:46:15","slug":"c-observer-pattern","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/c-observer-pattern\/","title":{"rendered":"C# Observer Pattern"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to use the C# observer pattern to notify objects (observers) when the state of another object (subject) changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to C# Observer pattern<\/h2>\n\n\n\n<p>The Observer pattern defines a one-to-many dependency between objects so that when one object (known as the subject) changes state, all its dependencies known as observers are notified and updated automatically.<\/p>\n\n\n\n<p>The following UML diagram illustrates the Observer pattern:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/csharptutorial.net\/wp-content\/uploads\/2023\/04\/CSharp-Observer-Pattern-1.svg\" alt=\"C# Observer Pattern\" class=\"wp-image-1587\"\/><\/figure>\n<\/div>\n\n\n<p>Here are the participants in the observer pattern:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ISubject<\/code> provides an <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-interface\/\">interface<\/a> for subscribing and unsubscribing <code>IObserver<\/code> objects.<\/li>\n\n\n\n<li><code>IObserver<\/code> defines an updating interface for objects that should be notified of changes in a subject.<\/li>\n\n\n\n<li><code><code>ConcreteSubject<\/code><\/code> stores the state of interest to the <code>ConcreteObserver<\/code> objects. The <code><code>ConcreteSubject<\/code><\/code> sends a notification to its observers when its state changes.<\/li>\n\n\n\n<li><code>ConcreteObserver<\/code> has a reference to a <code>ConcreteSubject<\/code> object. It also implements the <code>IObserver<\/code> interface to keep its state consistent with the state of the subject.<\/li>\n<\/ul>\n\n\n\n<p>The <code>ISubject<\/code> and <code>IObservers<\/code> objects are linked through a one-to-many relationship. It means that a subject can have multiple observers subscribed to it. <\/p>\n\n\n\n<p>When the state of the <code>ISubject<\/code> changes, it notifies all of its <code>IObserver<\/code> objects by calling their <code>Update<\/code> methods. <\/p>\n\n\n\n<p>The <code>IObserver<\/code> objects can then access the <code>ISubject<\/code>&#8216;s new state and update their own state.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C# Observer pattern example<\/h2>\n\n\n\n<p>Let&#8217;s say you want to develop a program that manages stock quotes. Whenever the price of the stock changes, you want to display it in the console as well as save the data into a file. To do that, you can use the Observer pattern.<\/p>\n\n\n\n<p>First, define an <code>IObserver<\/code> interface that has a method called <code><code>Update<\/code><\/code>. The <code><code>Update<\/code><\/code> method has two parameters <code>symbol<\/code> and <code>price<\/code>r representing the stock&#8217;s state:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IObserver<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> symbol, <span class=\"hljs-keyword\">decimal<\/span> price<\/span>)<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, define the <code>ISubject<\/code> interface that manages the <code>IObserver<\/code> objects such as subscribing, unsubscribing, and notifying the <code>IObserver<\/code> objects:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">ISubject<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Subscribe<\/span>(<span class=\"hljs-params\">IObserver observer<\/span>)<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Unsubscribe<\/span>(<span class=\"hljs-params\">IObserver observer<\/span>)<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">NotifyObservers<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, define the <code>Stock<\/code> class that implements the <code>ISubject<\/code> interface:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Stock<\/span> : <span class=\"hljs-title\">ISubject<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span> Symbol { <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>; }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">decimal<\/span> _price;\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">decimal<\/span> Price\n    {\n        <span class=\"hljs-keyword\">get<\/span> =&gt; _price;\n        <span class=\"hljs-keyword\">set<\/span>\n        {\n            <span class=\"hljs-keyword\">if<\/span> (_price != <span class=\"hljs-keyword\">value<\/span>)\n            {\n                _price = <span class=\"hljs-keyword\">value<\/span>;\n                NotifyObservers();\n            }\n\n        }\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Stock<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> symbol, <span class=\"hljs-keyword\">decimal<\/span> price<\/span>)<\/span>\n    {\n        Symbol = symbol;\n        Price = price;\n    }\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> List&lt;IObserver&gt; _observers = <span class=\"hljs-keyword\">new<\/span>();\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">NotifyObservers<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; _observers.ForEach(observer =&gt; observer.Update(Symbol, Price));\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Subscribe<\/span>(<span class=\"hljs-params\">IObserver observer<\/span>)<\/span> =&gt; _observers.Add(observer);\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Unsubscribe<\/span>(<span class=\"hljs-params\">IObserver observer<\/span>)<\/span> =&gt; _observers.Remove(observer);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>Stock<\/code> class has two properties <code>Symbol<\/code> and <code>Price<\/code> that represent stock symbol and price respectively.<\/p>\n\n\n\n<p>The <code>Stock<\/code> class maintains a list of <code><code>IObserver<\/code><\/code> objects as a <code>List&lt;IObserver&gt;<\/code>. Since the <code>Stock<\/code> class implements the <code>ISubject<\/code>  interface, it needs to provide implementations for the <code>Subscribe<\/code>, <code>Unsubscribe<\/code>, and <code>NotifyObservers<\/code> methods:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Subscribe<\/code> &#8211; adds an <code>IObserver<\/code> object to the <code>_observers<\/code> list.<\/li>\n\n\n\n<li><code>Unsubscribe<\/code> &#8211; removes an <code>IObserver<\/code> object from the <code>_observers<\/code> list.<\/li>\n\n\n\n<li><code>NotifyObservers<\/code> &#8211; notifies <code>IObserver<\/code> object in the <code>_observers<\/code> list by iterating the list and calling the <code>Update()<\/code> method of each object.<\/li>\n<\/ul>\n\n\n\n<p>In the <code>Price<\/code> setter, if the price changes, we call the <code>NotifiyObservers<\/code> method to notify the observers by calling their <code>Update<\/code> method.<\/p>\n\n\n\n<p>Fourth, define a <code>Display<\/code> class that displays the stock whenever the price changes. The <code>Display<\/code> class implements the <code>IObserver<\/code> interface:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Display<\/span> : <span class=\"hljs-title\">IObserver<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> ISubject _subject;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Display<\/span>(<span class=\"hljs-params\">ISubject subject<\/span>)<\/span>\n    {\n        _subject = subject;\n        _subject.Subscribe(<span class=\"hljs-keyword\">this<\/span>);\n    }\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> symbol, <span class=\"hljs-keyword\">decimal<\/span> price<\/span>)<\/span>\n    {\n        Console.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{symbol}<\/span>: <span class=\"hljs-subst\">{price}<\/span>\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Notice that the <code>Display<\/code> method maintains a member as an <code>ISubject<\/code> object. In the constructor, it assigns the subject to the <code>_subject<\/code> member and calls the <code>Subscribe()<\/code> method of the <code>_subject<\/code> object to subscribe itself as an observer. <\/p>\n\n\n\n<p>Fifth, define a <code>Logger<\/code> class that implements the <code>IObserver<\/code> interface:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Logger<\/span> : <span class=\"hljs-title\">IObserver<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> ISubject _subject;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> <span class=\"hljs-keyword\">string<\/span> _filename;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Logger<\/span>(<span class=\"hljs-params\">ISubject subject, <span class=\"hljs-keyword\">string<\/span> filename<\/span>)<\/span>\n    {\n        _subject = subject;\n        _subject.Subscribe(<span class=\"hljs-keyword\">this<\/span>);\n\n        _filename = filename;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Update<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> symbol, <span class=\"hljs-keyword\">decimal<\/span> price<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">using<\/span> <span class=\"hljs-keyword\">var<\/span> streamWriter = File.AppendText(_filename);\n        streamWriter.WriteLine(<span class=\"hljs-string\">$\"<span class=\"hljs-subst\">{symbol}<\/span>:<span class=\"hljs-subst\">{price}<\/span>\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>Logger<\/code> class is similar to the <code>Display<\/code> class except that it saves the stock data into a text file specified by the filename.<\/p>\n\n\n\n<p>Finally, define the Program class with the <code>Main()<\/code> method as the entry point of the program:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-comment\">\/\/ Create a new stock<\/span>\n        <span class=\"hljs-keyword\">var<\/span> stock = <span class=\"hljs-keyword\">new<\/span> Stock(<span class=\"hljs-string\">\"ABC\"<\/span>, <span class=\"hljs-number\">100<\/span>m);\n\n\n        <span class=\"hljs-comment\">\/\/ Create two observers Display &amp; Logger<\/span>\n        <span class=\"hljs-keyword\">var<\/span> display = <span class=\"hljs-keyword\">new<\/span> Display(stock);\n        <span class=\"hljs-keyword\">var<\/span> logger = <span class=\"hljs-keyword\">new<\/span> Logger(stock, <span class=\"hljs-string\">\"stock.txt\"<\/span>);\n\n        <span class=\"hljs-comment\">\/\/ Change the price, both display and logger<\/span>\n        <span class=\"hljs-comment\">\/\/ will be notified and updated<\/span>\n        stock.Price += <span class=\"hljs-number\">2<\/span>;\n        stock.Price -= <span class=\"hljs-number\">1<\/span>;\n\n        Console.ReadLine();\n\n        <span class=\"hljs-comment\">\/\/ remove the logger from the observer list<\/span>\n        stock.Unsubscribe(logger);\n\n        <span class=\"hljs-comment\">\/\/ Change the price, only the display is notified <\/span>\n        <span class=\"hljs-comment\">\/\/ and updated<\/span>\n        stock.Price += <span class=\"hljs-number\">3<\/span>;\n\n        Console.ReadLine();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the <code>Main()<\/code> method, we create a stock object as the subject and the <code>Display<\/code> and <code>Logger<\/code> objects as the observers. <\/p>\n\n\n\n<p>We then change the price of the stock twice, which updates the <code>Display<\/code> and <code>Logger<\/code> objects. As a result, you&#8217;ll see the console display the stock with new prices:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\">ABC: <span class=\"hljs-number\">102<\/span>\nABC: <span class=\"hljs-number\">101<\/span>\n<span class=\"hljs-function\">Press <span class=\"hljs-title\">Enter<\/span> (<span class=\"hljs-params\">or Return<\/span>) to <span class=\"hljs-keyword\">remove<\/span> the Logger <span class=\"hljs-keyword\">from<\/span> the observer list<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>and the <code>stock.txt<\/code> file will have two entries.<\/p>\n\n\n\n<p>If you hit the Enter (or Return key), the stock removes the <code>Logger<\/code> object from its observer list and changes its price. At this point, only the <code>Display<\/code> object is notified and updated:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\">ABC: <span class=\"hljs-number\">102<\/span>\nABC: <span class=\"hljs-number\">101<\/span>\n<span class=\"hljs-function\">Press <span class=\"hljs-title\">Enter<\/span> (<span class=\"hljs-params\">or Return<\/span>) to <span class=\"hljs-keyword\">remove<\/span> the Logger <span class=\"hljs-keyword\">from<\/span> the observer list\n\nABC: 104<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Because the <code>Logger<\/code> is not in the observer list, it is not notified and updated. Hence, the <code>stock.txt<\/code> has no new entries.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the C# Observer pattern to define a one-to-many dependency between objects, so that when one object changes, all its dependents are notified and updated automatically.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"1567\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/c-observer-pattern\/\"\n\t\t\t\tdata-post-title=\"C# Observer Pattern\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"1567\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/c-observer-pattern\/\"\n\t\t\t\tdata-post-title=\"C# Observer Pattern\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you&#8217;ll learn how to use the C# observer pattern to notify objects (observers) when the state of another object (subject) changes. Introduction to C# Observer pattern The Observer pattern defines a one-to-many dependency between objects so that when one object (known as the subject) changes state, all its dependencies known as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1441,"menu_order":24,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1567","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/comments?post=1567"}],"version-history":[{"count":5,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1567\/revisions"}],"predecessor-version":[{"id":1816,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1567\/revisions\/1816"}],"up":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1441"}],"wp:attachment":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/media?parent=1567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}