<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4394562672296169849</id><updated>2026-03-10T12:34:29.501+08:00</updated><category term="NHibernate"/><category term="C#"/><category term="Tweeting-Code"/><category term="ASP.NET MVC"/><category term="Design Pattern"/><category term="leetcode"/><category term="PostgreSQL"/><category term="SQL Server"/><category term="Tweeting-Troubleshooting"/><category term="Entity Framework"/><category term="Discipline"/><category term="SQL"/><category term="jQuery"/><category term="LINQ"/><category term="Fluent NHibernate"/><category term="Optimization"/><category term="ORM"/><category term="Troubleshooting"/><category term="WCF"/><category term="Mono"/><category term="Tweeting-How-To"/><category term="Unit Testing"/><category term=".NET"/><category term="ASP.NET"/><category term="Angular"/><category term="IIS"/><category term="SSRS"/><category term="Algorithm"/><category term="Database"/><category term="How-To"/><category term="Musings"/><category term="ServiceStack"/><category term="Concurrency"/><category term="Extension Methods"/><category term="JSON"/><category term="Lambda"/><category term="Localization"/><category term="MySQL"/><category term="Postgres"/><category term="React"/><category term="SQLite"/><category term="Stackoverflow Answer"/><category term="Stray Tweets"/><category term="Telerik"/><category term="ADO.NET"/><category term="Boilerplate Code"/><category term="Cargo Cult Programming"/><category term="Just C# Things"/><category term="Linq to NHibernate"/><category term="Visual Studio"/><category term="Waiting-For-Feature"/><category term="ASP.NET Web API"/><category term="Ajax"/><category term="Bikeshedding"/><category term="C"/><category term="Caching"/><category term="Code Dump"/><category term="Database Maintenance"/><category term="DryIoc"/><category term="Hibernate"/><category term="Idiomatic C#"/><category term="IoC"/><category term="JustAspNetThing"/><category term="LightInject"/><category term="Linq to SQL"/><category term="Logic"/><category term="MVVM"/><category term="Mac OS X"/><category term="MonoDevelop"/><category term="Moq"/><category term="NUnit"/><category term="Nifty-Sql-Function"/><category term="NotEnoughJquery"/><category term="Npgsql"/><category term="OOP"/><category term="One Trick Pony"/><category term="Open Source"/><category term="Reporting"/><category term="Repository Pattern"/><category term="Rule #1 Rule #2"/><category term="Setup"/><category term="SignalR"/><category term="Stackoverflow Issues"/><category term="ToTheEfnhX"/><category term="UTC"/><category term="Unity 2D"/><category term="Validation"/><category term="WPF"/><category term="javascript"/><category term="100th post"/><category term="200th post"/><category term="256th post"/><category term="ASP.NET Core"/><category term="AngularJS"/><category term="Apache"/><category term="Automation"/><category term="Benchmarking"/><category term="Blogging Search Keywords"/><category term="Bug"/><category term="C# Design Patterns"/><category term="C# F# C++"/><category term="Castle Windsor"/><category term="Cloud"/><category term="Code Intent"/><category term="ComboBox"/><category term="Context"/><category term="Convention-Over-Configuration"/><category term="DDD"/><category term="DRY"/><category term="Database Design"/><category term="Debunking Myths"/><category term="Domain Modelling"/><category term="Draw an owl"/><category term="Dream Setup"/><category term="Encryption"/><category term="Flexigrid"/><category term="Fun"/><category term="Game"/><category term="Gotcha"/><category term="HTML"/><category term="IE"/><category term="Identity"/><category term="Injectable"/><category term="Input"/><category term="Jargon"/><category term="Leaky Abstraction"/><category term="MVC"/><category term="Middleware"/><category term="ORM Discipline"/><category term="Oddities"/><category term="Oracle"/><category term="Output"/><category term="PLDT-ticks-me-off-to-no-end"/><category term="Porting"/><category term="Productivity"/><category term="Props"/><category term="Python"/><category term="REST API"/><category term="RedGate"/><category term="Redis"/><category term="SOA"/><category term="SSIS"/><category term="SayNoToDesignPattern-UseFirstClassWayToSolveProblems"/><category term="Shortcuts"/><category term="String Function"/><category term="Succinct Code"/><category term="Testing"/><category term="Tutorial"/><category term="Typo Error"/><category term="WCF Data Service"/><category term="timestamptz"/><category term="xkcd"/><title type='text'>class Programmer : IEnableMuch {</title><subtitle type='html'>&quot;Simplicity can&#39;t be bought later, it must be earned from the start&quot; -- DB</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>489</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-2956174078966806515</id><published>2025-06-29T15:16:00.008+08:00</published><updated>2025-06-30T00:25:07.859+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Optimization"/><title type='text'>changeDetectorRef.markForCheck()</title><content type='html'>When using &lt;em&gt;changeDetection: ChangeDetectionStrategy.OnPush&lt;/em&gt;, you need to call changeDetectorRef.markForCheck(). To avoid explicitly calling markForCheck, use async pipe on the observable variable. See line 13 on HTML below
&lt;pre class=&quot;brush: c#; highlight: [41]&quot;&gt;
@Component({
  selector: &amp;#39;app-contact-us&amp;#39;,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [JsonPipe, CommonModule, FormsModule, JsonPipe],
  templateUrl: &amp;#39;./contact-us.html&amp;#39;,
  styles: ``,
})

export class ContactUs implements OnInit {
  weather: any = null;
  weatherToo: any = null;
  weather$: any = null;
  weatherToo$: any = null;
  
  // not working
  // @Inject(ChangeDetectorRef) private readonly cdr!: ChangeDetectorRef;

  // working, but the obvious benefits are still not clear
  // private readonly cdr = inject(ChangeDetectorRef);

  constructor(private http: HttpClient, private cdr: ChangeDetectorRef) {}

  ngOnInit(): void  {
    this.http.get(&amp;#39;/api/WeatherForecast&amp;#39;).subscribe({
      next: value =&amp;gt; {
        // console.log({value});
        this.weather = value;
        this.cdr.markForCheck(); // will reflect on the UI

        // use this when you need it be immediate, like in setTimeout or 3rd party library
        // this.cdr.detectChanges();
      },
      error: (err) =&amp;gt; console.error(&amp;#39;http error&amp;#39;, err)
    });

    firstValueFrom(this.http.get(&amp;#39;/api/WeatherForecast&amp;#39;)).then(value =&amp;gt; {
      this.weatherToo = value;
      this.cdr.markForCheck();
    });

    this.weather$ = this.http.get(&amp;#39;/api/WeatherForecast&amp;#39;);
    // this.weather$.subscribe({
    //   next: (value: any) =&amp;gt; {
    //     console.log(&amp;#39;see&amp;#39;, {value});
    //   },
    //   error: (err: any) =&amp;gt; console.error(&amp;#39;http error&amp;#39;, err)
    // });

    this.weatherToo$ = this.http.get(&amp;#39;/api/WeatherForecast&amp;#39;);
  }
}
&lt;/pre&gt;
  
&lt;pre class=&quot;brush: c#; highlight: [13]&quot;&gt;
&amp;lt;div&amp;gt;
  &amp;lt;hr/&amp;gt;
  This works:&amp;lt;br/&amp;gt;
  {{weather | json}}
  &amp;lt;hr/&amp;gt;
  This too:&amp;lt;br/&amp;gt;
  {{weatherToo | json}}
  &amp;lt;hr/&amp;gt;
  This too, and it implicitly calls changeDetectorRef.markForCheck():&amp;lt;br/&amp;gt;
  {{weather$ | async | json}}

  &amp;lt;hr/&amp;gt;
  This will not show null:&amp;lt;br/&amp;gt;
  &amp;lt;ng-container *ngIf=&amp;quot;weatherToo$ | async as weatherWhenHaveValue&amp;quot;&amp;gt;{{ weatherWhenHaveValue | json }}&amp;lt;/ng-container&amp;gt;

  &amp;lt;hr/&amp;gt;
  &amp;lt;input [(ngModel)]=&amp;quot;name&amp;quot; placeholder=&amp;quot;Name&amp;quot;/&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

Ask this on Gemini or ChatGPT and see the &lt;a href=&quot;https://chatgpt.com/s/t_6860eafbe4dc8191887dacfbe2b93a9c&quot;&gt;answer&lt;/a&gt;:
&lt;pre class=&quot;console&quot;&gt;
does this recommendation kinda defeat the purpose of optimization for when change detection should take effect?

Option 3: Use AsyncPipe in the template
This forces Angular to update on observable emissions, even in OnPush:

weather$ = this.http.get(&amp;#39;/api/WeatherForecast&amp;#39;);

{{ weather$ | json }}
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/2956174078966806515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/change-detector-ref-mark-for-check.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2956174078966806515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2956174078966806515'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/change-detector-ref-mark-for-check.html' title='changeDetectorRef.markForCheck()'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-1914172519415520857</id><published>2025-06-28T18:51:00.003+08:00</published><updated>2025-06-28T19:41:07.244+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="REST API"/><title type='text'>Angular: proxy.conf.json; React: vite proxy</title><content type='html'>&lt;h3&gt;Angular&lt;/h3&gt;

angular.json
&lt;pre class=&quot;brush: c#; highlight: [6]&quot;&gt;
        &quot;serve&quot;: {
          &quot;options&quot;: {
            &quot;ssl&quot;: true,
            &quot;sslKey&quot;: &quot;ssl/key.pem&quot;,
            &quot;sslCert&quot;: &quot;ssl/cert.pem&quot;,
            &quot;proxyConfig&quot;: &quot;proxy.conf.json&quot;
          },
          &quot;builder&quot;: &quot;@angular/build:dev-server&quot;,
          &quot;configurations&quot;: {
            &quot;production&quot;: {
              &quot;buildTarget&quot;: &quot;react-analogous:build:production&quot;
            },
            &quot;development&quot;: {
              &quot;buildTarget&quot;: &quot;react-analogous:build:development&quot;
            }
          },
          &quot;defaultConfiguration&quot;: &quot;development&quot;
        },
&lt;/pre&gt;

proxy.conf.json&lt;br/&gt;
secure = false, just a self-signed certificate
&lt;pre class=&quot;brush: c#; highlight: [4]&quot;&gt;
{
  &amp;quot;/api&amp;quot;: {
    &amp;quot;target&amp;quot;: &amp;quot;https://localhost:7249&amp;quot;,
    &amp;quot;secure&amp;quot;: false,
    &amp;quot;changeOrigin&amp;quot;: true,
    &amp;quot;logLevel&amp;quot;: &amp;quot;debug&amp;quot;
  }
}
&lt;/pre&gt;


&lt;h3&gt;React&lt;/h3&gt;

React&#39;s vite proxy
&lt;pre class=&quot;brush: c#; highlight: [15,20]&quot;&gt;
import { defineConfig } from &amp;#39;vite&amp;#39;
import react from &amp;#39;@vitejs/plugin-react-swc&amp;#39;

import fs from &amp;#39;fs&amp;#39;;

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    https: {
      key: fs.readFileSync(&amp;#39;localhost-key.pem&amp;#39;) ,
      cert: fs.readFileSync(&amp;#39;localhost.pem&amp;#39;),
    },
    port: 3000,
    proxy: {
      &amp;#39;/api&amp;#39;: { // This is the prefix for requests you want to proxy
        target: &amp;#39;https://localhost:7249&amp;#39;, // The URL of your backend API
        changeOrigin: true, // Rewrites the origin header to match the target URL
        // rewrite: (path) =&amp;gt; path.replace(/^\/api/, &amp;#39;&amp;#39;), // Optional: remove &amp;#39;/api&amp;#39; from the request path sent to the backend
        secure: false, // Optional: if your backend uses HTTPS but has a self-signed certificate
        // agent: new http.Agent(), // Optional: if using HTTPS with a specific agent
      },
    },
  },
})
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/1914172519415520857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-proxy-conf-json-react-vite-proxy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/1914172519415520857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/1914172519415520857'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-proxy-conf-json-react-vite-proxy.html' title='Angular: proxy.conf.json; React: vite proxy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-5832219216314091155</id><published>2025-06-27T18:55:00.002+08:00</published><updated>2025-06-27T18:55:40.000+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Troubleshooting"/><title type='text'>Angular: Type &#39;Event&#39; is not assignable to type &#39;string&#39;.</title><content type='html'>If this innocent-looking code

&lt;pre class=&quot;brush: html&quot;&gt;
Color: &amp;lt;input [(ngModel)]=&amp;quot;color&amp;quot; /&amp;gt;
&lt;/pre&gt;


gives you this error:
&lt;pre class=&quot;console&quot;&gt;
Type &#39;Event&#39; is not assignable to type &#39;string&#39;.
&lt;/pre&gt;

Add FormsModule on imports:
&lt;pre class=&quot;brush: c#; highlight: [6]&quot;&gt;
@Component({
  selector: &amp;#39;app-root&amp;#39;,
  standalone: true,
  imports: [
    HoverHighlightDirective,
    // FormsModule, // uncomment this to remove the error: Type &amp;#39;Event&amp;#39; is not assignable to type &amp;#39;string&amp;#39;.
  ],
  templateUrl: &amp;#39;./main.html&amp;#39;,
})
export class App {
  name = &amp;#39;Angular&amp;#39;;

  color: string = &amp;#39;blue&amp;#39;;
}

bootstrapApplication(App);
&lt;/pre&gt;

Test code on stackblitz: &lt;a href=&quot;https://stackblitz.com/edit/angular-jjw6g1cv?file=src%2Fmain.ts&quot;&gt;https://stackblitz.com/edit/angular-jjw6g1cv?file=src%2Fmain.ts&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/5832219216314091155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-type-event-is-not-assignable-to-type-string.html.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/5832219216314091155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/5832219216314091155'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-type-event-is-not-assignable-to-type-string.html.html' title='Angular: Type &#39;Event&#39; is not assignable to type &#39;string&#39;.'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-8115885302555834896</id><published>2025-06-27T16:19:00.006+08:00</published><updated>2025-06-28T18:52:20.162+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><title type='text'>React: Just JavaScript ternary; Angular: ng-container, ngIf, else, ng-template</title><content type='html'>&lt;h3&gt;React&lt;/h3&gt;
&lt;pre class=&quot;brush: c#&quot;&gt;
import { useState } from &amp;#39;react&amp;#39;;
import &amp;#39;./App.css&amp;#39;;

function App() {
  const [theme, setTheme] = useState(&amp;#39;light&amp;#39;);

  return (
    &amp;lt;&amp;gt;
      &amp;lt;h1&amp;gt;React conditional rendering&amp;lt;/h1&amp;gt;

      {theme === &amp;#39;light&amp;#39; ? (
        &amp;lt;&amp;gt;
          &amp;lt;div&amp;gt;Hello Lightness&amp;lt;/div&amp;gt;
          &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;/&amp;gt;
      ) : (
        &amp;lt;&amp;gt;
          &amp;lt;div&amp;gt;Hello Darkness&amp;lt;/div&amp;gt;
          &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;/&amp;gt;
      )}

      &amp;lt;hr /&amp;gt;
      &amp;lt;button onClick={toggleTheme}&amp;gt;Toggle Theme (current: {theme})&amp;lt;/button&amp;gt;
    &amp;lt;/&amp;gt;
  );

  function toggleTheme() {
    setTheme((prev) =&amp;gt; (prev === &amp;#39;light&amp;#39; ? &amp;#39;dark&amp;#39; : &amp;#39;light&amp;#39;));
  }
}

export default App;
&lt;/pre&gt;

&lt;h3&gt;Angular&lt;/h3&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;h1&amp;gt;Angular Conditional Rendering&amp;lt;/h1&amp;gt;

&amp;lt;ng-container *ngIf=&amp;quot;theme === &amp;#39;light&amp;#39;; else darkness&amp;quot;&amp;gt;
  &amp;lt;div&amp;gt;Hello Lightness&amp;lt;/div&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/ng-container&amp;gt;

&amp;lt;ng-template #darkness&amp;gt;
  &amp;lt;div&amp;gt;Hello Darkness&amp;lt;/div&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/ng-template&amp;gt;

&amp;lt;br /&amp;gt;
&amp;lt;button (click)=&amp;quot;toggleTheme()&amp;quot;&amp;gt;Toggle Theme (Current: {{theme}})&amp;lt;/button&amp;gt;
&lt;/pre&gt;

&lt;pre class=&quot;brush: c#&quot;&gt;
import &amp;#39;zone.js&amp;#39;;
import { Component } from &amp;#39;@angular/core&amp;#39;;
import { bootstrapApplication } from &amp;#39;@angular/platform-browser&amp;#39;;
import { CommonModule } from &amp;#39;@angular/common&amp;#39;;

@Component({
  selector: &amp;#39;app-root&amp;#39;,
  standalone: true,
  imports: [CommonModule],
  templateUrl: &amp;#39;./main.html&amp;#39;,
})
export class App {
  name = &amp;#39;Angular&amp;#39;;

  theme = &amp;#39;light&amp;#39;;

  toggleTheme() {
    this.theme = this.theme === &amp;#39;light&amp;#39; ? &amp;#39;dark&amp;#39; : &amp;#39;light&amp;#39;;
  }
}

bootstrapApplication(App);
&lt;/pre&gt;


&lt;a href=&quot;https://stackblitz.com/edit/angular-nk4fbufg?file=src%2Fmain.ts&quot;&gt;Angular conditional rendering&lt;/a&gt; ◆ &lt;a href=&quot;https://stackblitz.com/edit/vitejs-vite-sg8vrxuc?file=src%2FApp.tsx&quot;&gt;React conditional rendering&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/8115885302555834896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/react-just-javascript-ternary-angular.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8115885302555834896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8115885302555834896'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/react-just-javascript-ternary-angular.html' title='React: Just JavaScript ternary; Angular: ng-container, ngIf, else, ng-template'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-4284627902442201995</id><published>2025-06-26T12:39:00.002+08:00</published><updated>2025-06-28T19:10:37.577+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Context"/><category scheme="http://www.blogger.com/atom/ns#" term="Injectable"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><title type='text'>React: Context; Angular: @Injectable</title><content type='html'>&lt;h3&gt;Bootstrapping React&lt;/h3&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot; /&amp;gt;
    &amp;lt;link rel=&amp;quot;icon&amp;quot; type=&amp;quot;image/svg+xml&amp;quot; href=&amp;quot;/vite.svg&amp;quot; /&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;Vite + React + TS&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;quot;root&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script type=&amp;quot;module&amp;quot; src=&amp;quot;/src/main.tsx&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;pre class=&quot;brush: c#; highlight: [5,14]&quot;&gt;
import React from &amp;#39;react&amp;#39;;
import ReactDOM from &amp;#39;react-dom/client&amp;#39;;
import App from &amp;#39;./App.tsx&amp;#39;;
import &amp;#39;./index.css&amp;#39;;
import { ThemeProvider } from &amp;#39;./contexts/ThemeContext.tsx&amp;#39;;

// Just for demo that context can reach even on children, grandchildren etc
function Main() {
  return &amp;lt;App&amp;gt;&amp;lt;/App&amp;gt;;
}

ReactDOM.createRoot(document.getElementById(&amp;#39;root&amp;#39;) as HTMLElement).render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;ThemeProvider&amp;gt;
      &amp;lt;Main /&amp;gt;
    &amp;lt;/ThemeProvider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/pre&gt;


&lt;h3&gt;Bootstrapping Angular&lt;/h3&gt;
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;My app&amp;lt;/title&amp;gt;
    &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot; /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;main-root&amp;gt;Loading...&amp;lt;/main-root&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;pre class=&quot;brush: c#&quot;&gt;
import &amp;#39;zone.js&amp;#39;;
import { Component } from &amp;#39;@angular/core&amp;#39;;
import { bootstrapApplication } from &amp;#39;@angular/platform-browser&amp;#39;;
import { AsyncPipe, NgStyle } from &amp;#39;@angular/common&amp;#39;;

import { App } from &amp;#39;./app/app&amp;#39;;

@Component({
  selector: &amp;#39;main-root&amp;#39;,
  standalone: true,
  imports: [AsyncPipe, NgStyle, App],
  template: `&amp;lt;app-root&amp;gt;&amp;lt;/app-root&amp;gt;`,
})
// Just for demo that service can reach even on children, grandchildren etc
export class Main {
  name = &amp;#39;Angular&amp;#39;;
}

bootstrapApplication(Main);
&lt;/pre&gt;

&lt;h3&gt;React&#39;s App component&lt;/h3&gt;
&lt;pre class=&quot;brush: c#; highlight: [2,9,16,22]&quot;&gt;
import &amp;#39;./App.css&amp;#39;;
import { useTheme } from &amp;#39;./contexts/ThemeContext&amp;#39;;

export default function App() {
  // Destructuring make names lose context
  // const { theme, toggleTheme } = useTheme();

  // I feel explicit is better, so things won&amp;#39;t appear as local
  const themeContext = useTheme();

  const name = &amp;#39;App&amp;#39;;

  return (
    &amp;lt;div
      style={{
        background: themeContext.theme === &amp;#39;dark&amp;#39; ? &amp;#39;#222&amp;#39; : &amp;#39;#eee&amp;#39;,
        color: themeContext.theme === &amp;#39;dark&amp;#39; ? &amp;#39;#eee&amp;#39; : &amp;#39;#222&amp;#39;,
        padding: &amp;#39;2rem&amp;#39;,
      }}
    &amp;gt;
      &amp;lt;h1&amp;gt;Hello from {name}!&amp;lt;/h1&amp;gt;
      &amp;lt;h3 onClick={themeContext.toggleTheme}&amp;gt;
        {themeContext.theme.toUpperCase()} MODE
      &amp;lt;/h3&amp;gt;
      &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://react.dev/&amp;quot;&amp;gt;
        Learn more about React
      &amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/pre&gt;

&lt;h3&gt;Angular&#39;s app-root component&lt;/h3&gt;
&lt;pre class=&quot;brush: c#; highlight: [22]&quot;&gt;
import { Component } from &amp;#39;@angular/core&amp;#39;;
import { ThemeContext } from &amp;#39;./contexts/theme.context&amp;#39;;
import { AsyncPipe, NgStyle } from &amp;#39;@angular/common&amp;#39;;

@Component({
  selector: &amp;#39;app-root&amp;#39;,
  standalone: true,
  templateUrl: &amp;#39;./app.html&amp;#39;,
  imports: [NgStyle, AsyncPipe],
})
export class App {
  name = &amp;#39;App&amp;#39;;

  // This works too, just seems complicated, and also it looks like local properties
  // theme$: Observable&amp;lt;Theme&amp;gt;;
  // toggleTheme: () =&amp;gt; void;

  // This works too, but it looks like local properties
  // get theme$() { return this.themeContext.theme$; }
  // toggleTheme() { this.themeContext.toggleTheme(); }

  constructor(public themeContext: ThemeContext) {
    // This works too, just seems complicated, and also it looks like local properties
    // ({theme$: this.theme$, toggleTheme: this.toggleTheme } = themeContext);
    // this.toggleTheme = this.toggleTheme.bind(themeContext);
    //
    // This works too, just seems complicated, and also it looks like local properties
    // this.theme$ = this.themeContext.theme$;
    // this.toggleTheme = this.themeContext.toggleTheme.bind(themeContext);
  }
}
&lt;/pre&gt;

&lt;pre class=&quot;brush: html; highlight: [3]&quot;&gt;
&amp;lt;div
  [ngStyle]=&amp;quot;{
  background: (themeContext.theme$ | async) === &amp;#39;dark&amp;#39; ? &amp;#39;#222&amp;#39; : &amp;#39;#eee&amp;#39;,
  color: (themeContext.theme$ | async) === &amp;#39;dark&amp;#39; ? &amp;#39;#eee&amp;#39; : &amp;#39;#222&amp;#39;,
  padding: &amp;#39;2rem&amp;#39;
}&amp;quot;
&amp;gt;
  &amp;lt;h1&amp;gt;Hello from {{ name }}!&amp;lt;/h1&amp;gt;
  &amp;lt;h3 (click)=&amp;quot;themeContext.toggleTheme()&amp;quot;&amp;gt;
    {{(themeContext.theme$ | async)?.toUpperCase()}} MODE
  &amp;lt;/h3&amp;gt;
  &amp;lt;a target=&amp;quot;_blank&amp;quot; href=&amp;quot;https://angular.dev/overview&amp;quot;&amp;gt;
    Learn more about Angular
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;h3&gt;React Context&lt;/h3&gt;
&lt;pre class=&quot;brush: c#; highlight: [7,10,12,16,21,26]&quot;&gt;
import { createContext, ReactNode, useContext, useState } from &amp;#39;react&amp;#39;;

type Theme = &amp;#39;light&amp;#39; | &amp;#39;dark&amp;#39;;

interface ThemeContextType {
  theme: Theme;
  toggleTheme: () =&amp;gt; void;
}

const ThemeContext = createContext&amp;lt;ThemeContextType | undefined&amp;gt;(undefined);

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [theme, setTheme] = useState&amp;lt;Theme&amp;gt;(&amp;#39;light&amp;#39;);

  return (
    &amp;lt;ThemeContext.Provider value={{ theme, toggleTheme }}&amp;gt;
      {children}
    &amp;lt;/ThemeContext.Provider&amp;gt;
  );

  function toggleTheme() {
    setTheme((prev) =&amp;gt; (prev === &amp;#39;light&amp;#39; ? &amp;#39;dark&amp;#39; : &amp;#39;light&amp;#39;));
  }
}

export function useTheme(): ThemeContextType {
  const context = useContext(ThemeContext);

  if (!context) {
    throw new Error(&amp;#39;useTheme must be used within a ThemeProvider&amp;#39;);
  }

  return context;
}
&lt;/pre&gt;

&lt;h3&gt;Angular @Injectable&lt;/h3&gt;
&lt;pre class=&quot;brush: c#; highlight: [6,9,13]&quot;&gt;
import { Injectable } from &amp;#39;@angular/core&amp;#39;;
import { BehaviorSubject } from &amp;#39;rxjs&amp;#39;;

export type Theme = &amp;#39;light&amp;#39; | &amp;#39;dark&amp;#39;;

@Injectable({
  providedIn: &amp;#39;root&amp;#39;,
})
export class ThemeContext {
  private themeSubject = new BehaviorSubject&amp;lt;Theme&amp;gt;(&amp;#39;light&amp;#39;);
  theme$ = this.themeSubject.asObservable();

  toggleTheme() {
    const newTheme = this.themeSubject.value === &amp;#39;light&amp;#39; ? &amp;#39;dark&amp;#39; : &amp;#39;light&amp;#39;;
    this.themeSubject.next(newTheme);
  }
}
&lt;/pre&gt;

&lt;a href=&quot;https://stackblitz.com/edit/vitejs-vite-zkxu5ukq?file=src%2Fcontexts%2FThemeContext.tsx&quot;&gt;React Context&lt;/a&gt; ◆ &lt;a href=&quot;https://stackblitz.com/edit/angular-u1m1wb1b?file=src%2Fapp%2Fcontexts%2Ftheme.context.ts&quot;&gt;Angular @Injectable&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/4284627902442201995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/react-context-angular-injectable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4284627902442201995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4284627902442201995'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/react-context-angular-injectable.html' title='React: Context; Angular: @Injectable'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-3903773845535390637</id><published>2025-06-25T22:44:00.008+08:00</published><updated>2025-06-28T19:22:34.948+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Angular"/><category scheme="http://www.blogger.com/atom/ns#" term="Input"/><category scheme="http://www.blogger.com/atom/ns#" term="Output"/><category scheme="http://www.blogger.com/atom/ns#" term="Props"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><title type='text'>Angular: @Input @Output; React: Just JavaScript</title><content type='html'>&lt;h3&gt;Angular @Input @Output&lt;/h3&gt;
&lt;br/&gt;
&lt;br/&gt;

Parent HTML:
&lt;pre class=&quot;brush: html; highlight: [6]&quot;&gt;
&amp;lt;div style=&quot;border: 1px solid green; padding: 10px;&quot;&amp;gt;
  &amp;lt;h2&amp;gt;Home Component&amp;lt;/h2&amp;gt;
  &amp;lt;p&amp;gt;Routing message: {{ (routeData$ | async)?.message }}&amp;lt;/p&amp;gt;
  &amp;lt;button (click)=&quot;increase()&quot;&amp;gt;Increase&amp;lt;/button&amp;gt;
  &amp;lt;app-contact-us [phoneNumber]=&quot;myPhone.toString()&quot; mainOffice=&quot;something&quot; [initialEmployeeCount]=&quot;homeEmployeeCount&quot;
    (onEmployeeCountChanged)=&quot;handleEmployeeCountChanged($event)&quot;&amp;gt;&amp;lt;/app-contact-us&amp;gt;
  &amp;lt;hr /&amp;gt;
  Parent employee count: {{homeEmployeeCount}}
  &amp;lt;br/&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

Parent TypeScript:
&lt;pre class=&quot;brush: c#; highlight: [44]&quot;&gt;
import { AsyncPipe, JsonPipe } from &#39;@angular/common&#39;;
import { Component, OnInit } from &#39;@angular/core&#39;;
import { ActivatedRoute } from &#39;@angular/router&#39;;
import { map, Observable, tap } from &#39;rxjs&#39;;
import { ContactUs } from &#39;./contact-us/contact-us&#39;;
import { HomeResolverData } from &#39;../../resolvers/home.resolver&#39;;

@Component({
  selector: &#39;app-home&#39;,
  imports: [AsyncPipe, ContactUs],
  templateUrl: &#39;./home.html&#39;,
  styles: ``,
})
export class Home implements OnInit {
  /**
   *
   */

  myPhone = 1314;
  homeEmployeeCount = 7;

  routeData$!: Observable&amp;lt;HomeResolverData&amp;gt;;

  constructor(private route: ActivatedRoute) {
    // console.log(JSON.stringify(this.route.data));
    // console.log(this.routeData$);
  }
  ngOnInit(): void {
    this.routeData$ = this.route.data.pipe(
      map((resolved) =&amp;gt; resolved[&#39;homeResolver&#39;] as HomeResolverData),
      tap((data) =&amp;gt;
        console.log(
          &#39;RESOLVER_DATA_CONSUMED: Resolver data is now available in component:&#39;,
          data
        )
      )
    );
  }

  increase() {
    ++this.myPhone;
  }

  handleEmployeeCountChanged($event: number) {
    this.homeEmployeeCount = $event;
  }
}
&lt;/pre&gt;

Child HTML:
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;div&amp;gt;

  &amp;lt;h4&amp;gt;Contact Us&amp;lt;/h4&amp;gt;


  Phone: {{phoneNumber}}&amp;lt;br/&amp;gt;
  Main Office: {{primaryOffice}}&amp;lt;br/&amp;gt;

  &amp;lt;button (click)=&quot;welcomeEmployee()&quot;&amp;gt;Welcome employee&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

Child TypeScript:
&lt;pre class=&quot;brush: c#; highlight: [14,18]&quot;&gt;
import { Component, EventEmitter, Input, Output } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-contact-us&#39;,
  imports: [],
  templateUrl: &#39;./contact-us.html&#39;,
  styles: ``
})
export class ContactUs {
    @Input() phoneNumber = &#39;&#39;;
    @Input(&#39;mainOffice&#39;) primaryOffice!: string;

    @Input() initialEmployeeCount = 0;
    @Output() onEmployeeCountChanged = new EventEmitter&amp;lt;number&amp;gt;();

    welcomeEmployee() {
      ++this.initialEmployeeCount;
      this.onEmployeeCountChanged.emit(this.initialEmployeeCount);
    }


}
&lt;/pre&gt;

&lt;br/&gt;
&lt;br/&gt;

&lt;h3&gt;React&lt;/h3&gt;
&lt;br/&gt;
&lt;br/&gt;

Parent HTML+TypeScript:
&lt;pre class=&quot;brush: c#; highlight: [20]&quot;&gt;
import { useLoaderData } from &quot;react-router&quot;;
import { ContactUs } from &quot;./Home/ContactUs&quot;;
import { useState } from &quot;react&quot;;

export default function Home() {
    const homeData = useLoaderData();

    const [myPhone, setMyPhone] = useState(1314);
    const [homeEmployeeCount, setHomeEmployeeCount] = useState(7);

    return (
        &amp;lt;&amp;gt;
            &amp;lt;h2&amp;gt;Home Component&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;Routing message: {homeData.message}&amp;lt;/p&amp;gt;
            &amp;lt;button onClick={increase}&amp;gt;Increase&amp;lt;/button&amp;gt;
            &amp;lt;ContactUs
                phoneNumber={myPhone.toString()}
                mainOffice=&quot;something&quot;
                initialEmployeeCount={homeEmployeeCount}
                onEmployeeCountChanged={handleEmployeeCountChanged}
            /&amp;gt;
            &amp;lt;hr /&amp;gt;
            &amp;lt;button onClick={batchIncreaseFlawed}&amp;gt;Batch Increase Flawed&amp;lt;/button&amp;gt;
            &amp;lt;button onClick={batchIncreaseCorrect}&amp;gt;
                Batch Increase Correct
            &amp;lt;/button&amp;gt;
            &amp;lt;hr /&amp;gt;
            Parent employee count: {homeEmployeeCount}
        &amp;lt;/&amp;gt;
    );

    function handleEmployeeCountChanged(newCount: number) {
        setHomeEmployeeCount(newCount);
    }

    function batchIncreaseFlawed() {
        setMyPhone(myPhone + 1);
        setMyPhone(myPhone + 1);
        setMyPhone(myPhone + 1);
    }

    function batchIncreaseCorrect() {
        setMyPhone((prev) =&amp;gt; prev + 1);
        setMyPhone((prev) =&amp;gt; prev + 1);
        setMyPhone((prev) =&amp;gt; prev + 1);
    }

    function increase() {
        setMyPhone((prev) =&amp;gt; prev + 1);
    }
}
&lt;/pre&gt;

Child HTML+TypeScript:
&lt;pre class=&quot;brush: c#; highlight: [14,32]&quot;&gt;
import { useState } from &quot;react&quot;;

type Params = {
    phoneNumber: string;
    mainOffice: string;
    initialEmployeeCount: number;
    onEmployeeCountChanged: (newCount: number) =&amp;gt; void;
};

export function ContactUs({
    phoneNumber,
    mainOffice: primaryOffice,
    initialEmployeeCount,
    onEmployeeCountChanged,
}: Params) {
    const [employeeCount, setEmployeeCount] = useState(initialEmployeeCount);

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h4&amp;gt;Contact Us&amp;lt;/h4&amp;gt;
            Phone: {phoneNumber} &amp;lt;br /&amp;gt;
            Main Office: {primaryOffice}&amp;lt;br /&amp;gt;
            
            &amp;lt;button onClick={welcomeEmployee}&amp;gt;Welcome employee&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    );

    function welcomeEmployee() {
        setEmployeeCount((prev) =&amp;gt; prev + 1);
        onEmployeeCountChanged(employeeCount);
    }
}
&lt;/pre&gt;

&lt;a href=&quot;https://stackblitz.com/edit/angular-tmincq9u?file=src%2Fmain.ts,src%2Findex.html,src%2Fcomponents%2Fcontact-us%2Fcontact-us.ts,src%2Fcomponents%2Fcontact-us%2Fcontact-us.html,src%2Fhome.html&quot;&gt;Angular: @Input @Output&lt;/a&gt; ◆ &lt;a href=&quot;https://stackblitz.com/edit/vitejs-vite-pwdgh11y?file=src%2Findex.css,src%2FContactUs.tsx,src%2Fmain.tsx,src%2FApp.tsx&quot;&gt;React&#39;s Angular @Input @Output&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/3903773845535390637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-input-output-react-just-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/3903773845535390637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/3903773845535390637'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/angular-input-output-react-just-javascript.html' title='Angular: @Input @Output; React: Just JavaScript'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-3058780718147713870</id><published>2025-06-22T20:51:00.002+08:00</published><updated>2025-06-23T15:03:05.992+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Middleware"/><title type='text'>.NET Middleware</title><content type='html'>Inline
&lt;pre class=&quot;brush: c#&quot;&gt;app.Use(async (context, next) =&amp;gt;
{
    var logger = app.Services.GetRequiredService&amp;lt;ILoggerFactory&amp;gt;()
        .CreateLogger(&quot;RequestLogger&quot;);

    logger.LogInformation(&quot;inline HTTP {Method} {Path}{Query}&quot;,
        context.Request.Method,
        context.Request.Path,
        context.Request.QueryString);
    
    await next();
});
&lt;/pre&gt;

Function
&lt;pre class=&quot;brush: c#&quot;&gt;app.Use(MyFuncMiddleware);
async Task MyFuncMiddleware(HttpContext context, Func&amp;lt;Task&amp;gt; next)&lt;/pre&gt;&lt;pre class=&quot;brush: c#&quot;&gt;{
    var logger = app.Services.GetRequiredService&amp;lt;ILoggerFactory&amp;gt;()
        .CreateLogger(&quot;RequestLogger&quot;);

    logger.LogInformation(&quot;func HTTP {Method} {Path}{Query}&quot;,
        context.Request.Method,
        context.Request.Path,
        context.Request.QueryString);
    
    await next();
}
&lt;/pre&gt;

HOC
&lt;pre class=&quot;brush: c#&quot;&gt;app.Use(MyHocMiddleware());
Func&amp;lt;HttpContext, Func&amp;lt;Task&amp;gt;, Task&amp;gt; MyHocMiddleware()
{
     var logger = app.Services.GetRequiredService&amp;lt;ILoggerFactory&amp;gt;()
         .CreateLogger(&quot;RequestLogger&quot;);
     
    return async (context, next) =&amp;gt;
    {
        logger.LogInformation(&quot;hoc HTTP {Method} {Path}{Query}&quot;,
            context.Request.Method,
            context.Request.Path,
            context.Request.QueryString);
    
        await next();
    };
}
&lt;/pre&gt;

Fluent HOC
&lt;pre class=&quot;brush: c#&quot;&gt;app.UseMyFluentHocMiddleware();

public static class MyFluentHocMiddlewareExtensions
{
    // Extension method for IApplicationBuilder to register our custom middleware
    public static IApplicationBuilder UseMyFluentHocMiddleware(this IApplicationBuilder builder)
    {
        var logger = builder.ApplicationServices.GetRequiredService&amp;lt;ILoggerFactory&amp;gt;()
          .CreateLogger(&quot;RequestLogger&quot;);
        
        return builder.Use(async (context, next) =&amp;gt; 
        {
            logger.LogInformation(&quot;fluent HTTP {Method} {Path}{Query}&quot;,
                 context.Request.Method,
                 context.Request.Path,
                 context.Request.QueryString);

             await next();
        });
    }
}
&lt;/pre&gt;

Fluent Class
&lt;pre class=&quot;brush: c#&quot;&gt;app.UseMyFluentClassMiddleware();

// Constructor: The RequestDelegate representing the next middleware MUST be the first parameter.
// Other dependencies (like ILogger) are injected by the DI container.

public class MyClassMiddleware(RequestDelegate next, ILogger&amp;lt;MyClassMiddleware&amp;gt; logger)
{
    // Invoke or InvokeAsync method: This is where the actual middleware logic resides.
    // It must return Task and take HttpContext as the first parameter.
    public async Task InvokeAsync(HttpContext context)
    {
        logger.LogInformation(&quot;myClass HTTP {Method} {Path}{Query}&quot;,
            context.Request.Method,
            context.Request.Path,
            context.Request.QueryString);
        
        await next(context);

        // logger.LogInformation($&quot;[Class Middleware] Outgoing response status: {context.Response.StatusCode}&quot;);
    }
}

// Optional: An extension method to make registering the class middleware more fluent
public static class MyClassMiddlewareExtensions
{
    public static IApplicationBuilder UseMyFluentClassMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware&amp;lt;MyClassMiddleware&amp;gt;();
    }
}

&lt;/pre&gt;&lt;chinese-words-separator--notification-area class=&quot;xcws-notif-host&quot; id=&quot;chinese-words-separator--notification-area&quot;&gt;&lt;div&gt;&lt;style&gt;        

.xcws-notif-host div {
    all: revert;
}

.xcws-notif-host &gt; div {
    position: fixed; 
    top: 0px;
    right: 4px;
    max-width: 480px;
    display: flex; 
    flex-direction: column;
    z-index: 99999999999;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification {
  position:relative;
  padding: 4px 8px;
  color: white;
  font-family: &quot;Helvetica&quot;;
  font-size: 12pt;
  border-radius: 5px;
  margin: 5px 0px 3px 5px;
  opacity: 0;
  left: 250px;
  white-space: pre-wrap;

  box-shadow: 3px 3px 5px 3px rgba(128,128,128,0.5);
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification * {
    color: inherit;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification  &gt; div &gt; .xcws-hz-learned {
    text-align: left;
    color: white;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification  &gt; div &gt; .xcws-hz-learned &gt; span {
    color: inherit;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification  &gt; div &gt; .xcws-hz-learned &gt; span.xcws-hz-itself {
    font-size: 1.4em;
}

.xcws-notif-host &gt; div .xcws-hz-pair-info {
    display: block;
    display: flex;
    justify-content: space-between;
    white-space: pre;
    align-items: baseline;
}

.xcws-notif-host &gt; div .xcws-hz-pair-info &gt; div {
    margin: 0;
    color: white;
}

@-webkit-keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
    }

    5% {
        display: block;
        opacity: 1;
        left: 0px;
    }

    75% {
        display: block;
        opacity: 1;
        left: 0px;
    }

    100% {
        display: block;
        opacity: 0;
        left: 250px;

    }
}

.xcws-notif-host &gt; div .xcws-hz--fade_out {
  -webkit-animation: fadeInFromNone 5s ease-out;
}

.xcws-notif-host &gt; div .xcws-hz--move_element_up {
  -webkit-animation: fadeInFromNone 5s ease-out;
}

.xcws-notif-host &gt; div .xcws-hz--do_after_goan{
   opacity: 1;
   overflow-y: hidden;
   visibility: hidden;
   left: 0px ;
   -webkit-animation: xcws-hz---after_goan 0.5s;
}

@keyframes xcws-hz---after_goan {
    0% {
        visibility:hidden;
        overflow-y: hidden;
    }
    100% {
        padding: 0px;
        height: 0px;
    }
}


.xcws-notif-host &gt; div &gt; .xcws-hz-notification.xcws-hz-notification-type--success {
    background: green;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification.xcws-hz-notification-type--error {
    background: orangered;
}

.xcws-notif-host &gt; div &gt; .xcws-hz-notification.xcws-hz-notification-type--info {
    background: dodgerblue;
}

    &lt;/style&gt;&lt;/div&gt;&lt;/chinese-words-separator--notification-area&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/3058780718147713870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2025/06/net-middleware.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/3058780718147713870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/3058780718147713870'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2025/06/net-middleware.html' title='.NET Middleware'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-4707721431727290161</id><published>2021-04-05T20:33:00.005+08:00</published><updated>2021-04-05T20:33:50.161+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1748. Sum of Unique Elements. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int SumOfUnique(int[] nums) {
        var hs = 
            from n in nums
            group n by n into g
            where g.Count() == 1
            select g.Key;
        
        return hs.Sum();
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/sum-of-unique-elements/submissions/&#39;&gt;https://leetcode.com/problems/sum-of-unique-elements/submissions/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/4707721431727290161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/04/leetcode-everyday-1748-sum-of-unique-elements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4707721431727290161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4707721431727290161'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/04/leetcode-everyday-1748-sum-of-unique-elements.html' title='Leetcode Everyday: 1748. Sum of Unique Elements. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-7828177313362906376</id><published>2021-03-29T22:28:00.007+08:00</published><updated>2021-03-29T22:48:29.699+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 617. Merge Two Binary Trees. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public TreeNode MergeTrees(TreeNode root1, TreeNode root2) =&amp;gt;
        root1 != null || root2 != null ? 
            new TreeNode(
                (root1?.val ?? 0) + (root2?.val ?? 0),
                MergeTrees(root1?.left, root2?.left),
                MergeTrees(root1?.right, root2?.right)            
            )
        : 
            null;                        
}

// TODO: optimize without allocating
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/merge-two-binary-trees/&#39;&gt;https://leetcode.com/problems/merge-two-binary-trees/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/7828177313362906376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-617-merge-two-binary-trees.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7828177313362906376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7828177313362906376'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-617-merge-two-binary-trees.html' title='Leetcode Everyday: 617. Merge Two Binary Trees. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-7974595235853248635</id><published>2021-03-20T14:37:00.005+08:00</published><updated>2021-03-20T14:46:02.674+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 728. Self Dividing Numbers. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public IList&amp;lt;int&amp;gt; SelfDividingNumbers(int left, int right) {
        var list = new List&amp;lt;int&amp;gt;();
        for (var i = left; i &amp;lt;= right; ++i) {
            for (var n = i; n &amp;gt; 0; n /= 10) {
                var toDivide = n % 10;
                if (toDivide == 0 || i % toDivide != 0) {
                    goto goNextNumber;
                }                
            }
            list.Add(i);
            
goNextNumber:;
        }
        return list;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/self-dividing-numbers/&#39;&gt;https://leetcode.com/problems/self-dividing-numbers/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/7974595235853248635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-728-self-dividing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7974595235853248635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7974595235853248635'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-728-self-dividing.html' title='Leetcode Everyday: 728. Self Dividing Numbers. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-8174465316621025780</id><published>2021-03-16T11:39:00.002+08:00</published><updated>2021-03-16T11:39:28.082+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1351. Count Negative Numbers in a Sorted Matrix. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public int CountNegatives(int[][] grid) {
    var count = 0;
    foreach (var line in grid) {
        for (var i = 0; i &amp;lt; line.Length; ++i) {
            if (line[i] &amp;lt;0) {
                count += line.Length - i;
                break;
            }
        }
    }
    return count;
}

// TODO: Create a binary search approach
&lt;/pre&gt;

Functional:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
	public int CountNegatives(int[][] grid) =&amp;gt; grid.SelectMany(line =&amp;gt; line).Count(n =&amp;gt; n &amp;lt; 0);    
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/count-negative-numbers-in-a-sorted-matrix/&#39;&gt;https://leetcode.com/problems/count-negative-numbers-in-a-sorted-matrix/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/8174465316621025780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1351-count-negative.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8174465316621025780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8174465316621025780'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1351-count-negative.html' title='Leetcode Everyday: 1351. Count Negative Numbers in a Sorted Matrix. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-4055797673175038507</id><published>2021-03-14T12:33:00.003+08:00</published><updated>2021-07-20T11:56:30.799+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1464. Maximum Product of Two Elements in an Array. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;public class Solution {
    public int MaxProduct(int[] nums) {
        // first and second highest
        var first = 0;
        var second = 0;
        
        foreach (var n in nums) {
            if (n &amp;gt; first) {
                (first, second) = (n, first);
            } else if (n &amp;gt; second) {
                second = n;
            }
        }
        
        return (first - 1) * (second - 1);
    }
}&lt;/pre&gt;

Functional Programming:
&lt;br /&gt;
&lt;pre class=&quot;brush: c#&quot;&gt;public class Solution {
    public int MaxProduct(int[] nums) =&amp;gt;
        nums.OrderByDescending(n =&amp;gt; n).Take(2)
            .Aggregate((a, b) =&amp;gt; (a-1) * (b-1));        
}
&lt;/pre&gt;

Source: &lt;a href=&quot;https://leetcode.com/problems/maximum-product-of-two-elements-in-an-array/&quot;&gt;https://leetcode.com/problems/maximum-product-of-two-elements-in-an-array/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/4055797673175038507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/eetcode-everyday-1464-maximum-product-of-two-elements-in-an-array.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4055797673175038507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4055797673175038507'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/eetcode-everyday-1464-maximum-product-of-two-elements-in-an-array.html' title='Leetcode Everyday: 1464. Maximum Product of Two Elements in an Array. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-8950162719882514921</id><published>2021-03-13T00:02:00.003+08:00</published><updated>2021-03-13T00:02:32.487+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1374. Generate a String With Characters That Have Odd Counts. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string GenerateTheString(int n) =&amp;gt;
        new string(&#39;a&#39;, n - (n%2 ^ 1)) + new string(&#39;b&#39;, 1 - n%2);
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/generate-a-string-with-characters-that-have-odd-counts/&#39;&gt;https://leetcode.com/problems/generate-a-string-with-characters-that-have-odd-counts/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/8950162719882514921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1374-generate-string-with-characters-that-have-odd-counts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8950162719882514921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8950162719882514921'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1374-generate-string-with-characters-that-have-odd-counts.html' title='Leetcode Everyday: 1374. Generate a String With Characters That Have Odd Counts. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-7370553054801632303</id><published>2021-03-10T23:30:00.008+08:00</published><updated>2021-03-11T00:53:43.820+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1304. Find N Unique Integers Sum up to Zero. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int[] SumZero(int n) {
        var list = new int[n];
         
        var ndx = 0;
        for (var i = 1; i &amp;lt;= n / 2; ++i) {
            list[ndx++] = i;
            list[ndx++] = -i;
        }
         
        if (n % 2 == 1) {
            list[ndx] = 0;
        }
         
        return list;
    }
}
&lt;/pre&gt;

Alternative:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int[] SumZero(int n) {
        var list = new int[n];
         
        for (int i = 1, ndx = 0; i &amp;lt;= n / 2; ++i, ndx += 2) {
            list[ndx] = i;
            list[ndx+1] = -i;
        }
         
        if (n % 2 == 1) {
            list[^1] = 0;
        }
         
        return list;
    }
}
&lt;/pre&gt;

This works, but is confusing:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int[] SumZero(int n) {
        var list = new int[n];
         
        var i = 0;
        while (i &amp;lt; n / 2) {
            list[i++] = i;
            list[^i] = -i;
        }
          
        if (n % 2 == 1) {
            list[i] = 0;
        }
          
        return list;
    }
}
&lt;/pre&gt;


Source: &lt;a href=&#39;https://leetcode.com/problems/find-n-unique-integers-sum-up-to-zero/submissions/&#39;&gt;https://leetcode.com/problems/find-n-unique-integers-sum-up-to-zero/submissions/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/7370553054801632303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1304-find-n-unique-integers-sum-up-to-zero.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7370553054801632303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7370553054801632303'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1304-find-n-unique-integers-sum-up-to-zero.html' title='Leetcode Everyday: 1304. Find N Unique Integers Sum up to Zero. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-4575258712602958355</id><published>2021-03-10T00:05:00.007+08:00</published><updated>2021-03-10T10:02:10.652+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1370. Increasing Decreasing String. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string SortString(string s) {
        var sorted = s.Distinct().OrderBy(x =&amp;gt; x).ToList();
        var sortedDesc = sorted.OrderByDescending(x =&amp;gt; x).ToList();
        
        var sb = new StringBuilder();
        
        var isAscending = true;
        for (; s.Length &amp;gt; 0; isAscending = !isAscending) { 
            var toSort = isAscending ? sorted : sortedDesc;            
            foreach (var c in toSort) {
                var i = s.IndexOf(c);
                if (i &amp;gt;= 0) {
                    s = s.Remove(i, 1);
                    sb.Append(c);
                }
            }
        }
        
        return sb.ToString();
    }
}
&lt;/pre&gt;

Optimized
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string SortString(string s) {
        const int z = 26;
        var freq = new int[z];
        
        var sLength = s.Length;
        var sb = new char[sLength]; // think of this as StringBuilder
        
        foreach (var c in s){
            ++freq[c - &#39;a&#39;];
        }
        
        for (var i = 0; i &amp;lt; sLength; ){
            
            for (var small = 0; small &amp;lt; z; ++small){
                if (freq[small] &amp;gt; 0){
                    --freq[small];
                    sb[i] = (char)(&#39;a&#39; + small);
                    
                    ++i;
                }
            }
            
            for (var large = z - 1; large &amp;gt;= 0; --large){
                if (freq[large] &amp;gt; 0){
                    --freq[large];
                    sb[i] = (char)(&#39;a&#39; + large);

                    ++i;
                }
            }
            
        }
        
        return new string(sb);
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/increasing-decreasing-string/submissions/&#39;&gt;https://leetcode.com/problems/increasing-decreasing-string/submissions/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/4575258712602958355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1370-increasing-decreasing-string.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4575258712602958355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4575258712602958355'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1370-increasing-decreasing-string.html' title='Leetcode Everyday: 1370. Increasing Decreasing String. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-5549065125086158416</id><published>2021-03-08T23:05:00.006+08:00</published><updated>2021-03-09T08:34:38.591+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1704. Determine if String Halves Are Alike. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public bool HalvesAreAlike(string s) {
        var half = s.Length / 2;
        var a = s.Substring(0, half);
        var b = s.Substring(s.Length - half, half);
        
        var vowels = new HashSet&amp;lt;char&amp;gt;() {&#39;a&#39;, &#39;e&#39;, &#39;i&#39;, &#39;o&#39;, &#39;u&#39;, &#39;A&#39;, &#39;E&#39;, &#39;I&#39;, &#39;O&#39;, &#39;U&#39;};
        
        return a.Count(c =&amp;gt; vowels.Any(v =&amp;gt; char.ToUpper(c) == v))
            == b.Count(c =&amp;gt; vowels.Any(v =&amp;gt; char.ToUpper(c) == v));
    }
}
&lt;/pre&gt;

Optimized:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public bool HalvesAreAlike(string s) {
        var half = s.Length / 2;        
        var vowels = new HashSet&amp;lt;char&amp;gt;() {&#39;a&#39;, &#39;e&#39;, &#39;i&#39;, &#39;o&#39;, &#39;u&#39;, &#39;A&#39;, &#39;E&#39;, &#39;I&#39;, &#39;O&#39;, &#39;U&#39;};
                
        var count = 0;        
        for (var i = 0; i &amp;lt; half; ++i) {
            if (vowels.Contains(s[i]))
                ++count;
            
            if (vowels.Contains(s[^(i + 1)])) 
                --count;
        }        
        return count == 0;
    }
}
&lt;/pre&gt;


&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public bool HalvesAreAlike(string s) {
        var half = s.Length / 2;        
                
        var count = 0;        
        for (var i = 0; i &amp;lt; half; ++i) {
            if (s[i] switch {
                &#39;A&#39; =&amp;gt; true,
                &#39;a&#39; =&amp;gt; true,
                &#39;E&#39; =&amp;gt; true,
                &#39;e&#39; =&amp;gt; true,
                &#39;I&#39; =&amp;gt; true,
                &#39;i&#39; =&amp;gt; true,
                &#39;O&#39; =&amp;gt; true,
                &#39;o&#39; =&amp;gt; true,
                &#39;U&#39; =&amp;gt; true,
                &#39;u&#39; =&amp;gt; true,
                _ =&amp;gt; false                    
            }) {
                ++count;
            }
            
            if (s[(^(i + 1))] switch {
                &#39;A&#39; =&amp;gt; true,
                &#39;a&#39; =&amp;gt; true,
                &#39;E&#39; =&amp;gt; true,
                &#39;e&#39; =&amp;gt; true,
                &#39;I&#39; =&amp;gt; true,
                &#39;i&#39; =&amp;gt; true,
                &#39;O&#39; =&amp;gt; true,
                &#39;o&#39; =&amp;gt; true,
                &#39;U&#39; =&amp;gt; true,
                &#39;u&#39; =&amp;gt; true,
                _ =&amp;gt; false                    
            }) {
                --count; 
            }
        }        
        return count == 0;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/determine-if-string-halves-are-alike/&#39;&gt;https://leetcode.com/problems/determine-if-string-halves-are-alike/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/5549065125086158416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1704-determine-if.halves-are-alike.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/5549065125086158416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/5549065125086158416'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1704-determine-if.halves-are-alike.html' title='Leetcode Everyday: 1704. Determine if String Halves Are Alike. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-7610926188072199214</id><published>2021-03-07T22:25:00.004+08:00</published><updated>2021-03-07T22:53:55.014+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1436. Destination City. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string DestCity(IList&amp;lt;IList&amp;lt;string&amp;gt;&amp;gt; paths) {
        var pathLookup = new Dictionary&amp;lt;string, string&amp;gt;();
        
        foreach (var path in paths) {
            pathLookup[path.First()] = path.Last();
        }
        
        var source = pathLookup.FirstOrDefault().Key;
        while (pathLookup.TryGetValue(source, out string destination)) {
            source = destination;
        }   
        
        return source;
    }
}
&lt;/pre&gt;

Functional programming:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string DestCity(IList&amp;lt;IList&amp;lt;string&amp;gt;&amp;gt; paths) =&gt;        
        paths.Single(dest =&amp;gt; !paths.Any(source =&amp;gt; dest.Last() == source.First())).Last();
}
&lt;/pre&gt;

Optimized:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string DestCity(IList&amp;lt;IList&amp;lt;string&amp;gt;&amp;gt; paths) {
        var outgoing = new HashSet&amp;lt;string&amp;gt;();        
        outgoing.UnionWith(paths.Select(path =&amp;gt; path.First()));
        
        foreach (var path in paths) {
            if (!outgoing.Contains(path.Last())) {
                return path.Last();
            }
        }
        
        return null;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/destination-city/submissions/&#39;&gt;https://leetcode.com/problems/destination-city/submissions/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/7610926188072199214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1436-destination-city.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7610926188072199214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/7610926188072199214'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1436-destination-city.html' title='Leetcode Everyday: 1436. Destination City. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-8812805156743933143</id><published>2021-03-06T01:46:00.006+08:00</published><updated>2021-03-06T11:03:32.728+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1309. Decrypt String from Alphabet to Integer Mapping. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
using System.Text.RegularExpressions;

public class Solution {
    public string FreqAlphabets(string s) {
        var lookup = new Dictionary&amp;lt;string, char&amp;gt;();
        
        var rx = new Regex(@&quot;\d{2}#|\d{1}&quot;);
        var alphabet = &quot;12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#&quot;;
        
        var c = &#39;a&#39;;
        foreach (var match in rx.Matches(alphabet).Cast&amp;lt;Match&amp;gt;()) {
            lookup[match.Value] = c++;
        }
        
        var sb = new StringBuilder();        
        foreach (var match in rx.Matches(s).Cast&amp;lt;Match&amp;gt;()) {
            sb.Append(lookup[match.Value]);
        }
        
        return sb.ToString();        
    }
}
&lt;/pre&gt;

Optimized: 
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string FreqAlphabets(string s) {
        var sb = new StringBuilder();
        for (var i = 0; i &amp;lt; s.Length; ) {
            if (i+2 &amp;lt; s.Length &amp;&amp; s[i+2] == &#39;#&#39;) {
                sb.Append((char)(&#39;a&#39; + (s[i]-&#39;0&#39;)*10 + s[i+1]-&#39;0&#39; - 1));                
                i += 3;
            } else {        
                sb.Append((char)(&#39;a&#39; + s[i]-&#39;0&#39; - 1));
                ++i;
            }
        }
        return sb.ToString();                
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/decrypt-string-from-alphabet-to-integer-mapping/&#39;&gt;https://leetcode.com/problems/decrypt-string-from-alphabet-to-integer-mapping/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/8812805156743933143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1309-decrypt-string-from-alphabet-to-integer-mapping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8812805156743933143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8812805156743933143'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1309-decrypt-string-from-alphabet-to-integer-mapping.html' title='Leetcode Everyday: 1309. Decrypt String from Alphabet to Integer Mapping. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-350598742604296481</id><published>2021-03-04T12:25:00.000+08:00</published><updated>2021-03-04T12:25:02.699+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1725. Number Of Rectangles That Can Form The Largest Square. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int CountGoodRectangles(int[][] rectangles) {
        var minCounts = new Dictionary&amp;lt;int, int&amp;gt;();    
        
        foreach (var r in rectangles) {
            var min = Math.Min(r[0], r[1]);           
            minCounts[min] = 
                (minCounts.TryGetValue(min, out int value) ? value : 0) + 1;        
        }
                            
        return minCounts[minCounts.Keys.Max()];
    }    
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/number-of-rectangles-that-can-form-the-largest-square/&#39;&gt;https://leetcode.com/problems/number-of-rectangles-that-can-form-the-largest-square/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/350598742604296481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1725-number-of-rectangles-that-can-form-the-largest-square.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/350598742604296481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/350598742604296481'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1725-number-of-rectangles-that-can-form-the-largest-square.html' title='Leetcode Everyday: 1725. Number Of Rectangles That Can Form The Largest Square. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-4099037740142433798</id><published>2021-03-03T09:24:00.002+08:00</published><updated>2021-03-03T10:00:46.024+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1323. Maximum 69 Number. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int Maximum69Number (int num) {
        
        var sNum = num.ToString();
        var foundAt = sNum.IndexOf(&#39;6&#39;);
                   
        if (foundAt &amp;gt;= 0) {
            return num +  (3 * (int)Math.Pow(10, sNum.Length - foundAt - 1));
        }
        
        return num;        
    }
}
&lt;/pre&gt;

Same speed as above (32ms), but uses less memory:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int Maximum69Number (int num) {
    
            var add = 0;

            for (int temp = num, step = 1; temp &amp;gt; 0; temp /= 10, step *= 10) {
                if (temp % 10 == 6) {
                    add = step * 3;
                }
            }

            return num + add;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/maximum-69-number/&#39;&gt;https://leetcode.com/problems/maximum-69-number/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/4099037740142433798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1323-maximum-69.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4099037740142433798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/4099037740142433798'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1323-maximum-69.html' title='Leetcode Everyday: 1323. Maximum 69 Number. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-2346348569215061162</id><published>2021-03-02T13:05:00.002+08:00</published><updated>2021-03-02T13:45:28.297+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1572. Matrix Diagonal Sum. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int DiagonalSum(int[][] mat) {
        var sum = 0;        
     
        var length = mat.Length;
        for (var walk = 0; walk &amp;lt; length; ++walk) {
            sum += mat[walk][walk] + mat[^(walk + 1)][walk];
        }   
        
        // exclude center
        var center = Math.DivRem(length, 2, out int remainder);
        if (remainder == 1) {
            sum -= mat[center][center];
        }           
  
        return sum;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/matrix-diagonal-sum/&#39;&gt;https://leetcode.com/problems/matrix-diagonal-sum/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/2346348569215061162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1572-matrix-diagonal.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2346348569215061162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2346348569215061162'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-1572-matrix-diagonal.html' title='Leetcode Everyday: 1572. Matrix Diagonal Sum. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-146799627866129447</id><published>2021-03-01T11:29:00.002+08:00</published><updated>2021-03-01T11:50:02.655+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 832. Flipping an Image. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int[][] FlipAndInvertImage(int[][] image) {
        foreach (var row in image) {
            for (var col = 0; col &amp;lt; row.Length / 2; ++col) {                
                // shorthand:
                (row[col], row[^(col+1)]) = (row[^(col+1)], row[col]);
                
                // longhand:
                // (row[col], row[row.Length - (col+1)]) = (row[row.Length - (col+1)], row[col]);
            }            
            
            for (var col = 0; col &amp;lt; row.Length; ++col) {
                row[col] ^= 1;
            }
        }
        
        return image;
    }
}
&lt;/pre&gt;

Optimized:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int[][] FlipAndInvertImage(int[][] image) {
        foreach (var row in image) {
            var half = row.Length / 2;
            for (var col = 0; col &amp;lt; half; ++col) {                
                // shorthand:
                (row[col], row[^(col+1)]) = (row[^(col+1)] ^ 1, row[col] ^ 1);
                
                // longhand:
                // (row[col], row[row.Length - (col+1)]) = (row[row.Length - (col+1)], row[col]);
            }                        
        }
        
        if (image.Length &amp;gt; 0 &amp;&amp; image[0].Length % 2 == 1) {
            var middle = image[0].Length / 2;
            foreach (var row in image) {
                row[middle] ^= 1;
            }
        }
        
        return image;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/flipping-an-image/&#39;&gt;https://leetcode.com/problems/flipping-an-image/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/146799627866129447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-832-flipping-image.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/146799627866129447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/146799627866129447'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/03/leetcode-everyday-832-flipping-image.html' title='Leetcode Everyday: 832. Flipping an Image. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-1187629228024307182</id><published>2021-02-26T12:47:00.006+08:00</published><updated>2021-03-04T20:19:41.118+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1252. Cells with Odd Values in a Matrix. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public int OddCells(int n, int m, int[][] indices) {
        var mat = new int[n, m];
        
        foreach (var index in indices) {
            var ri = index[0];                
            for (var col = 0; col &amp;lt; m; ++col) {
                ++mat[ri, col];
            }
            
            var ci = index[1];
            for (var row = 0; row &amp;lt; n; ++row) {
                ++mat[row, ci];
            }
        }
        
        
        // functional programming:
        // return mat.Cast&amp;lt;int&amp;gt;().Count(number =&amp;gt; number % 2 == 1);
        
        
        // this would work:
        // var oddCount = 0;
        // for (var ni = 0; ni &amp;lt; n; ++ni) {
        //     for (var mi = 0; mi &amp;lt; m; ++mi) {
        //         oddCount += mat[ni, mi] % 2;
        //     }
        // }
        
        
        // this is better and faster. C# can look at array as if it is one-dimensional
        var oddCount = 0;
        foreach (var number in mat) {
            oddCount += number % 2;
        }        
        return oddCount;
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/cells-with-odd-values-in-a-matrix/&#39;&gt;https://leetcode.com/problems/cells-with-odd-values-in-a-matrix/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/1187629228024307182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-1252-cells-with-odd-values-in-matrix.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/1187629228024307182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/1187629228024307182'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-1252-cells-with-odd-values-in-matrix.html' title='Leetcode Everyday: 1252. Cells with Odd Values in a Matrix. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-8412218574641917933</id><published>2021-02-24T09:15:00.006+08:00</published><updated>2021-02-24T09:47:35.774+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 804. Unique Morse Code Words. Easy</title><content type='html'>Functional programming:

&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    readonly string[] morseCodes = new[] {
        &quot;.-&quot;,&quot;-...&quot;,&quot;-.-.&quot;,&quot;-..&quot;,&quot;.&quot;,
        &quot;..-.&quot;,&quot;--.&quot;,&quot;....&quot;,&quot;..&quot;,&quot;.---&quot;,
        &quot;-.-&quot;,&quot;.-..&quot;,&quot;--&quot;,&quot;-.&quot;,&quot;---&quot;,
        &quot;.--.&quot;,&quot;--.-&quot;,&quot;.-.&quot;,&quot;...&quot;,&quot;-&quot;,
        &quot;..-&quot;,&quot;...-&quot;,&quot;.--&quot;,&quot;-..-&quot;,&quot;-.--&quot;,&quot;--..&quot;
    };
    
    public int UniqueMorseRepresentations(string[] words) =&amp;gt;
        words.Select(word =&amp;gt;
            word.Skip(1).Aggregate(
                morseCodes[word[0] - &#39;a&#39;].ToString(),
                (txMorse, current) =&amp;gt; txMorse + morseCodes[current - &#39;a&#39;]
            )
        ).Distinct().Count();    
}
&lt;/pre&gt;

Imperative programming:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {

    public int UniqueMorseRepresentations(string[] words) {        
        var morseCodes = new[] {
            &quot;.-&quot;,&quot;-...&quot;,&quot;-.-.&quot;,&quot;-..&quot;,&quot;.&quot;,
            &quot;..-.&quot;,&quot;--.&quot;,&quot;....&quot;,&quot;..&quot;,&quot;.---&quot;,
            &quot;-.-&quot;,&quot;.-..&quot;,&quot;--&quot;,&quot;-.&quot;,&quot;---&quot;,
            &quot;.--.&quot;,&quot;--.-&quot;,&quot;.-.&quot;,&quot;...&quot;,&quot;-&quot;,
            &quot;..-&quot;,&quot;...-&quot;,&quot;.--&quot;,&quot;-..-&quot;,&quot;-.--&quot;,&quot;--..&quot;
        };
        
		var distinctMorses = new HashSet&lt;string&gt;();
        var buildMorse = new StringBuilder();
        foreach (var word in words) {
        
            foreach (var c in word) {
                buildMorse.Append(morseCodes[c - &#39;a&#39;]);
            }
            
            var txMorse = buildMorse.ToString();
            buildMorse.Clear();
            
            if (!distinctMorses.Contains(txMorse)) {
                distinctMorses.Add(txMorse);
            }
        }        
        return distinctMorses.Count;
    }      
          
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/unique-morse-code-words/&#39;&gt;https://leetcode.com/problems/unique-morse-code-words/&lt;/a&gt;
</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/8412218574641917933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-804-unique-morse-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8412218574641917933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/8412218574641917933'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-804-unique-morse-code.html' title='Leetcode Everyday: 804. Unique Morse Code Words. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4394562672296169849.post-2045814836016585505</id><published>2021-02-23T10:20:00.003+08:00</published><updated>2021-02-23T11:57:12.128+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="leetcode"/><title type='text'>Leetcode Everyday: 1021. Remove Outermost Parentheses. Easy</title><content type='html'>&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string RemoveOuterParentheses(string s) {
        var sb = new StringBuilder();        
    
        var opList = new Dictionary&amp;lt;char, int&amp;gt; {
            [&#39;(&#39;] = 1,
            [&#39;)&#39;] = -1
        };
        
        int depth = 0;
        foreach (var c in s) {
            var op = opList[c];
            depth += op;
            if (op == 1 &amp;&amp; depth &amp;gt; 1 || op == -1 &amp;&amp; depth &amp;gt; 0) {
                sb.Append(c);
            }
        }
        
        return sb.ToString();
    }
}
&lt;/pre&gt;

Compact condition:
&lt;pre class=&quot;brush: c#&quot;&gt;
public class Solution {
    public string RemoveOuterParentheses(string s) {
        var sb = new StringBuilder();
         
     
        // KeyValue&amp;lt;op, depth&amp;gt;
        // op = 1 = increment
        // op = -1 = decrement
        var opList = new Dictionary&amp;lt;char, KeyValuePair&amp;lt;int, int&amp;gt;&amp;gt; {
            [&#39;(&#39;] = new KeyValuePair&amp;lt;int, int&amp;gt;(1, 1),
            [&#39;)&#39;] = new KeyValuePair&amp;lt;int, int&amp;gt;(-1, 0)
        };
         
         
        int depth = 0;
        foreach (var c in s) {
            var (op, opDepth) = opList[c];
            depth += op;
                  
            if (depth &amp;gt; opDepth) {
                sb.Append(c);
            }
        }
         
        return sb.ToString();
    }
}
&lt;/pre&gt;

Source: &lt;a href=&#39;https://leetcode.com/problems/remove-outermost-parentheses/&#39;&gt;https://leetcode.com/problems/remove-outermost-parentheses/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.ienablemuch.com/feeds/2045814836016585505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-1021-remove-outermost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2045814836016585505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4394562672296169849/posts/default/2045814836016585505'/><link rel='alternate' type='text/html' href='http://www.ienablemuch.com/2021/02/leetcode-everyday-1021-remove-outermost.html' title='Leetcode Everyday: 1021. Remove Outermost Parentheses. Easy'/><author><name>IEnableMuch</name><uri>http://www.blogger.com/profile/01393635235961303977</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>