<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C# Archives - CodeJourney.net</title>
	<atom:link href="https://www.codejourney.net/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codejourney.net/tag/c/</link>
	<description>Building real-world software with AI 🤖</description>
	<lastBuildDate>Thu, 03 Oct 2024 13:41:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://i0.wp.com/www.codejourney.net/wp-content/uploads/2018/10/cropped-512px-na-512px-JPEG-BEZ-NAPISU-1.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>C# Archives - CodeJourney.net</title>
	<link>https://www.codejourney.net/tag/c/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123174533</site>	<item>
		<title>What is Mutation Testing and Why Should You Use It?</title>
		<link>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/</link>
					<comments>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 18:22:58 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mutation testing]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4825</guid>

					<description><![CDATA[<p>Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI? The answer to all these questions is mutation testing. Interested? Read on 😉 Code Coverage &#8211; Our Old Friend You probably know what&#8230;</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI?</p>



<p class="wp-block-paragraph">The answer to all these questions is <strong>mutation testing</strong>. Interested? Read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4825"></span>



<h2 class="wp-block-heading">Code Coverage &#8211; Our Old Friend</h2>



<p class="wp-block-paragraph">You probably know what <a href="https://en.wikipedia.org/wiki/Code_coverage">code coverage</a> is. Traditionally, many teams tend to measure how good their tests&#8217; suite is by percentage line / statements / functions coverage. Some even require this metric to be 100%. Let&#8217;s start with this well-known approach first.</p>



<p class="wp-block-paragraph">We are working with <code>TicketsPriceCalculator</code> class today. It contains some simple business logic:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133062269" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator.ts content, created by dsibinski on 04:08PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator.ts">
        <tr>
          <td id="file-ticketspricecalculator-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator-ts-LC1" class="blob-code blob-code-inner js-file-line">export class TicketsPriceCalculator {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator-ts-LC2" class="blob-code blob-code-inner js-file-line">  calculateTotalTicketsPrice(tickets: Ticket[]): number {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator-ts-LC3" class="blob-code blob-code-inner js-file-line">    if (tickets.length === 0) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator-ts-LC4" class="blob-code blob-code-inner js-file-line">      return 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator-ts-LC5" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator-ts-LC7" class="blob-code blob-code-inner js-file-line">    let totalPrice = tickets.reduce((sum, ticket) =&gt; sum + ticket.price, 0);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator-ts-LC8" class="blob-code blob-code-inner js-file-line">    const businessClassTickets = tickets.filter(</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator-ts-LC9" class="blob-code blob-code-inner js-file-line">      (ticket) =&gt; ticket.isBusinessClass</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-ticketspricecalculator-ts-LC10" class="blob-code blob-code-inner js-file-line">    ).length;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-ticketspricecalculator-ts-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-ticketspricecalculator-ts-LC12" class="blob-code blob-code-inner js-file-line">    let totalDiscountToApply = 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-ticketspricecalculator-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-ticketspricecalculator-ts-LC14" class="blob-code blob-code-inner js-file-line">    // Apply discounts based on total price</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-ticketspricecalculator-ts-LC15" class="blob-code blob-code-inner js-file-line">    if (totalPrice &gt; 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-ticketspricecalculator-ts-LC16" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.25;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-ticketspricecalculator-ts-LC17" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 1000 &amp;&amp; totalPrice &lt;= 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-ticketspricecalculator-ts-LC18" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-ticketspricecalculator-ts-LC19" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 500 &amp;&amp; totalPrice &lt;= 1000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-ticketspricecalculator-ts-LC20" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.15;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-ticketspricecalculator-ts-LC21" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt;= 200 &amp;&amp; totalPrice &lt;= 500) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-ticketspricecalculator-ts-LC22" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-ticketspricecalculator-ts-LC23" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-ticketspricecalculator-ts-LC24" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-ticketspricecalculator-ts-LC25" class="blob-code blob-code-inner js-file-line">    // Apply additional discount based on number of tickets</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-ticketspricecalculator-ts-LC26" class="blob-code blob-code-inner js-file-line">    if (tickets.length &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-ticketspricecalculator-ts-LC27" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.05;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-ticketspricecalculator-ts-LC28" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-ticketspricecalculator-ts-LC29" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-ticketspricecalculator-ts-LC30" class="blob-code blob-code-inner js-file-line">    // Apply business class discounts</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-ticketspricecalculator-ts-LC31" class="blob-code blob-code-inner js-file-line">    if (businessClassTickets &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-ticketspricecalculator-ts-LC32" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-ticketspricecalculator-ts-LC33" class="blob-code blob-code-inner js-file-line">    } else if (businessClassTickets &gt;= 5) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-ticketspricecalculator-ts-LC34" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-ticketspricecalculator-ts-LC35" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-ticketspricecalculator-ts-LC36" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-ticketspricecalculator-ts-LC37" class="blob-code blob-code-inner js-file-line">    return totalPrice * (1 &#8211; totalDiscountToApply);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-ticketspricecalculator-ts-LC38" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-ticketspricecalculator-ts-LC39" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d/raw/d388fec49bd951d520a8d0af93c07907c122ce27/ticketsPriceCalculator.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d#file-ticketspricecalculator-ts" class="Link--inTextBlock">
          ticketsPriceCalculator.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">As you can see, the class has one function whith returns the total price to be paid for a set of tickets. On the way, it applies various discounts based on some business rules. Fair enough.</p>



<p class="wp-block-paragraph">It&#8217;s a critical piece of business logic for the app we&#8217;re working on, but it has never had any tests. We were asked to write unit tests for this class. Our manager strictly requires the code coverage to be 100%. Let&#8217;s do it then. We will go line by line, analyze the business logic and add the tests. Below, you can see the results of running those tests (you can find the tests code <a href="https://gist.github.com/dsibinski/cfc8d36cf7fe45bb9114b950fa898766">here</a>):</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="839" height="427" data-attachment-id="4840" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/1-unit-tests-initial/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" data-orig-size="839,427" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1-unit-tests-initial" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=839%2C427&#038;ssl=1" alt="Unit tests before using mutation testing. We have 8 unit tests, all passing. Our code coverage (line, functions, statements, branches) is 100%" class="wp-image-4840" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?w=839&amp;ssl=1 839w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=768%2C391&amp;ssl=1 768w" sizes="(max-width: 839px) 100vw, 839px" /></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Wow, that&#8217;s awesome! We did a great job. We have <strong>8 unit tests which provide 100% statements, branch, functions and lines coverage</strong>!</p>



<p class="wp-block-paragraph">So now we are really safe, aren&#8217;t we? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Yeah&#8230; until you know what mutation testing is <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">What Is Mutation Testing?</h2>



<p class="wp-block-paragraph">The idea of mutation testing is to <em>mutate</em> (change) our code. Mutation testing tools introduce changes into our production code. These changes can be really anything &#8211; from reverting a condition of an <code>if</code> statement, to changing some operators or changing a <code>string</code> value. For instance, here are some logical mutations <a href="https://stryker-mutator.io/">Stryker Mutator</a> is able to introduce (you can find the list of all mutations supported by Stryker <a href="https://stryker-mutator.io/docs/mutation-testing-elements/supported-mutators/">here</a>):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" decoding="async" width="445" height="320" data-attachment-id="4845" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/2-stryker-logical-mutations/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" data-orig-size="445,320" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2-stryker-logical-mutations" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?resize=445%2C320&#038;ssl=1" alt="Logical operator mutations supported by Stryker Mutator" class="wp-image-4845"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">In effect, they generate modified versions of our code, which are called <em>mutants</em>. Makes sense <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Each mutant contains a single modification in our source code. What happens next is crucial. Mutation testing tool takes this mutant (it is used as the code under tests now) and executes all of our unit tests against it. The result may be twofold:</p>



<ul class="wp-block-list">
<li>all tests have passed. In other words, the <em>mutant has</em> <em>survived</em>. <strong>This is a bad situation</strong>. It implies that the modification of our source code was not detected by our tests</li>



<li>at least one test has failed. In other words, the <em>mutant has been killed</em>. <strong>This is a good scenario</strong>. It means that our tests detect changes in the production code and efficiently cover this particular scenario.</li>
</ul>



<p class="wp-block-paragraph">The flow is more or less like this <a href="https://peterevans.dev/posts/mutation-testing/">schema from Peter Evans&#8217; blog</a> presents:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-recalc-dims="1" decoding="async" width="353" height="580" data-attachment-id="4847" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/3-mutation-test-schema/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" data-orig-size="353,580" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3-mutation-test-schema" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?resize=353%2C580&#038;ssl=1" alt="Schema of mutation testing" class="wp-image-4847" style="width:353px;height:auto"/></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">But why would anyone change the production code on purpose by introducing some stupid changes? It may seem counterintuitive for now, but let&#8217;s see how we can use it to our leverage.</p>



<h2 class="wp-block-heading">Mutation Testing with Stryker Mutator</h2>



<p class="wp-block-paragraph">Let&#8217;s clearly state what we are starting with:</p>



<p class="wp-block-paragraph"><strong>8 unit tests, 100% code coverage</strong></p>



<p class="wp-block-paragraph">Let&#8217;s now run mutation testing on our code. We are using TypeScript here, so let&#8217;s go with <a href="https://stryker-mutator.io/">Stryker Mutator</a>.</p>



<p class="wp-block-paragraph">Here&#8217;s the result of running Stryker with <code>npx stryker run</code> on our code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="958" height="163" data-attachment-id="4854" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/4-stryker-mutator-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" data-orig-size="958,163" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4-stryker-mutator-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=958%2C163&#038;ssl=1" alt="Mutation test result - first run. Mutation score 78%, survived mutants 15" class="wp-image-4854" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?w=958&amp;ssl=1 958w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 958px) 100vw, 958px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">As you can see, 53 mutants were killed, but 15 of them survived. This gives us a mutation score of 78%. Let&#8217;s call it <em>mutation coverage</em> from now on. So to make it clear, this is our starting situation:</p>



<p class="wp-block-paragraph"><strong>8 unit tests, 100% code coverage, 78% mutation coverage</strong></p>



<p class="wp-block-paragraph">Let&#8217;s now see how to kill those remaining mutants.</p>



<h2 class="wp-block-heading">Killing First Mutants</h2>



<p class="wp-block-paragraph">In order to kill the mutants and improve our mutation score, we need to write more unit tests. Sounds logical, doesn&#8217;t it?</p>



<p class="wp-block-paragraph">If still not, let&#8217;s take a deeper look at mutation tests results in VS Code. Stryker lists details of every survived mutant, for example this one:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="864" height="198" data-attachment-id="4855" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/5-stryker-mutant-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" data-orig-size="864,198" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5-stryker-mutant-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=864%2C198&#038;ssl=1" alt="First mutant generated by Stryker" class="wp-image-4855" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?w=864&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=768%2C176&amp;ssl=1 768w" sizes="auto, (max-width: 864px) 100vw, 864px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Stryker changed the greater or equal (<code>>=</code>) operator to greater operator (<code>></code>). This is a very common and very useful mutation. It usually means that our tests don&#8217;t cover the edge case associated with this particular condition.</p>



<p class="wp-block-paragraph">In this case, the edge case value seems to be <code>5</code>. More precisely, what happens if the number of business class tickets is <em>exactly 5</em>? We don&#8217;t know, because there is no test for this particular edge case!</p>



<p class="wp-block-paragraph">Let&#8217;s add it:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133063837" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator_edgecase-test-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator_edgeCase.test.ts content, created by dsibinski on 05:23PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator_edgeCase.test.ts">
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC1" class="blob-code blob-code-inner js-file-line">  test(&quot;should apply 10% discount if there are exactly 5 business class tickets&quot;, () =&gt; {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC2" class="blob-code blob-code-inner js-file-line">    const tickets = Array.from({ length: 5 }, () =&gt; ({</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC3" class="blob-code blob-code-inner js-file-line">      price: 10,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC4" class="blob-code blob-code-inner js-file-line">      isBusinessClass: true,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC5" class="blob-code blob-code-inner js-file-line">    }));</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC7" class="blob-code blob-code-inner js-file-line">    const totalPrice = calculator.calculateTotalTicketsPrice(tickets);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC8" class="blob-code blob-code-inner js-file-line">    expect(totalPrice).toBe(45); // 10% discount</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC9" class="blob-code blob-code-inner js-file-line">  });</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1/raw/836811b2f5ba7f306346a9c11f4fe7de42ce2b89/ticketsPriceCalculator_edgeCase.test.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1#file-ticketspricecalculator_edgecase-test-ts" class="Link--inTextBlock">
          ticketsPriceCalculator_edgeCase.test.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The test passes. Let&#8217;s run mutation tests again:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="961" height="166" data-attachment-id="4856" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/6-stryker-mutator-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" data-orig-size="961,166" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6-stryker-mutator-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=961%2C166&#038;ssl=1" alt="Struker Mutator second run - already 14 mutants survived and almost 80% mutation coverage" class="wp-image-4856" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?w=961&amp;ssl=1 961w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=768%2C133&amp;ssl=1 768w" sizes="auto, (max-width: 961px) 100vw, 961px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">That&#8217;s it! We have a new unit test and 1 more mutant killed <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" />  Current state:</p>



<p class="wp-block-paragraph"><strong>9 (+1) unit tests, 100% code coverage, 79% mutation coverage</strong></p>



<p class="wp-block-paragraph">I think you&#8217;re now getting what this is all about. We should be adding unit tests to cover the edge cases detected by mutations until all (or most) mutants are killed.</p>



<h2 class="wp-block-heading">Mutation Testing &#8211; Free Unit Tests Generator</h2>



<p class="wp-block-paragraph">After adding 1 more test, the results look as follows:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="960" height="164" data-attachment-id="4859" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/7-stryker-mutator-3/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" data-orig-size="960,164" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7-stryker-mutator-3" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=960%2C164&#038;ssl=1" alt="Struker mutator with 10 tests - 86% mutation coverage" class="wp-image-4859" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?w=960&amp;ssl=1 960w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><strong>10 (+2) unit tests, 100% code coverage, 86% mutation coverage</strong></p>



<p class="wp-block-paragraph">Finally, this is what we managed to get after a few minutes of work:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="959" height="165" data-attachment-id="4860" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/8-stryker-mutator-4/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" data-orig-size="959,165" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="8-stryker-mutator-4" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=959%2C165&#038;ssl=1" alt="" class="wp-image-4860" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?w=959&amp;ssl=1 959w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=768%2C132&amp;ssl=1 768w" sizes="auto, (max-width: 959px) 100vw, 959px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">And we now have 17 unit tests in our suite! The final score looks like that:</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /><strong>17 (+9) unit tests, 100% code coverage, 96% mutation coverage</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Notice what happened here. <strong>We started with 8 unit tests and finished with 17! This is awesome! That&#8217;s how mutation testing is a free unit tests generator</strong>. And you don&#8217;t even need AI for that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">What&#8217;s more, the generated mutations even forced me to make a little tweak to the production code. It exposed some things that didn&#8217;t make sense. I could make this change to the production code, because my tests&#8217; suite was already quite substantial.</p>



<p class="wp-block-paragraph">Note that I didn&#8217;t push to gain 100% mutation coverage. The 3 mutants that survived don&#8217;t make much sense in our case. I encourage you to <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">get the code</a> and execute <code>npx stryker run</code> in the application folder to see for yourself <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">The percentage value doesn&#8217;t matter in that case. What matters is that we got 9 new unit tests and our tests&#8217; suite is more robust. Now we can go and tell our manager that the business-critical code is well tested <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">So What Now?</h2>



<p class="wp-block-paragraph">I hope you see how valuable mutation testing is. It&#8217;s not a perfect tool that suits all cases. For example, it&#8217;s not easy to use mutation testing for complex legacy code. However, if your logic is nicely isolated, it could be a great tool. Especially if your production code heavily depends on calculations and many conditions. You may be surprised how many edge cases mutation testing can find.</p>



<p class="wp-block-paragraph">I also love using mutation testing with TDD. These two techniques nicely complement each other.</p>



<p class="wp-block-paragraph">I encourage you to go and try mutation testing. There are different mutation tools for various programming languages:</p>



<ul class="wp-block-list">
<li>C#, JavaScript, TypeScript, Scala: <a href="https://stryker-mutator.io/">Stryker Mutator</a></li>



<li>Ruby: <a href="https://github.com/mbj/mutant">mutant</a></li>



<li>Java: <a href="https://pitest.org/">pitest</a></li>



<li>PHP: <a href="https://infection.github.io/">Infection</a></li>



<li>C++: <a href="https://github.com/nlohmann/mutate_cpp">Mutate++</a></li>
</ul>



<p class="wp-block-paragraph">&#8230;and probably many more. Just do some research for the language you work with and give it a try <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Because <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">testing</a> is cool, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can find the full source code used in this article <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">here</a>.</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4825</post-id>	</item>
		<item>
		<title>Typing API Responses With Zod</title>
		<link>https://www.codejourney.net/typing-api-responses-with-zod/</link>
					<comments>https://www.codejourney.net/typing-api-responses-with-zod/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Mon, 11 Jul 2022 07:00:00 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[zod]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4093</guid>

					<description><![CDATA[<p>Have you ever needed to synchronize types in your frontend app with the backend API? If you ever had an API action defined like that in your controller: and fetched this data using TypeScript in the following way: at some point, you probably also experienced the desynchronization of backend (C#, in our example) and frontend&#8230;</p>
<p>The post <a href="https://www.codejourney.net/typing-api-responses-with-zod/">Typing API Responses With Zod</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Have you ever needed to synchronize types in your frontend app with the backend API?</p>



<p class="wp-block-paragraph">If you ever had an API action defined like that in your controller:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117275988" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-aspnetcontrollersample-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="AspNetControllerSample.cs content, created by dsibinski on 02:22PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="AspNetControllerSample.cs">
        <tr>
          <td id="file-aspnetcontrollersample-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-aspnetcontrollersample-cs-LC1" class="blob-code blob-code-inner js-file-line">public record UserViewModel(Guid Id, string Name, string LastName, string Login, </td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-aspnetcontrollersample-cs-LC2" class="blob-code blob-code-inner js-file-line">    bool IsActive, int LoyaltyPoints, AddressViewModel? Address = null);</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-aspnetcontrollersample-cs-LC3" class="blob-code blob-code-inner js-file-line">    </td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-aspnetcontrollersample-cs-LC4" class="blob-code blob-code-inner js-file-line">// &#8230;</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-aspnetcontrollersample-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-aspnetcontrollersample-cs-LC6" class="blob-code blob-code-inner js-file-line">public List&lt;UserViewModel&gt; AllUsers()</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-aspnetcontrollersample-cs-LC7" class="blob-code blob-code-inner js-file-line">{</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-aspnetcontrollersample-cs-LC8" class="blob-code blob-code-inner js-file-line">    var usersViewModels = TestDataGenerator.GetTestUsers();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-aspnetcontrollersample-cs-LC9" class="blob-code blob-code-inner js-file-line">    return usersViewModels.OrderBy(uvm =&gt; uvm.Name).ToList();</td>
        </tr>
        <tr>
          <td id="file-aspnetcontrollersample-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-aspnetcontrollersample-cs-LC10" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/bf658760106de7269ebf3d0f351c0411/raw/2336445c10cd9b76b7a5b9af3a747eeaddfb75c4/AspNetControllerSample.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/bf658760106de7269ebf3d0f351c0411#file-aspnetcontrollersample-cs" class="Link--inTextBlock">
          AspNetControllerSample.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">and fetched this data using TypeScript in the following way:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
https://gist.github.com/dsibinski/44438baa3b6ece08a191b0e918c01a77
</div></figure>



<p class="wp-block-paragraph">at some point, you probably also experienced the desynchronization of backend (C#, in our example) and frontend (TypeScript) types definitions. What if someone has changed the C# version of <code>UserViewModel</code>, but no one corrected its TypeScript&#8217;s equivalent? </p>



<p class="wp-block-paragraph">Your TypeScript fetching code will tell nothing about that. <strong>There will be no error, even though the fetched data doesn&#8217;t match the expected <code>UserViewModel</code> type</strong>.</p>



<p class="wp-block-paragraph">I&#8217;ll try to address this issue in this article <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Let&#8217;s see how typing API responses with <code>zod</code> can help us here.</p>



<span id="more-4093"></span>



<h2 class="wp-block-heading">Synchronization of Backend and Frontend API Typings</h2>



<p class="wp-block-paragraph">First, why would we want to keep the backend and frontend models in sync?</p>



<p class="wp-block-paragraph">For me, that&#8217;s the purpose of using TypeScript. <strong>We want our code to be as well-typed as possible</strong>. For instance, we normally want the data displayed to the user to be fully typed. TypeScript enhances our programming experience by providing us with typing information. Thanks to that, we know <em>what is what</em> and <em>what contains</em> <em>what</em>. We also express what types of data we expect in particular cases.</p>



<p class="wp-block-paragraph">The APIs mostly return JSON data, which can be anything. Because of that, it is much easier to have the data returned from the API fully typed in TypeScript. Thanks to that, <strong>we know what properties are available on the data models received from the API and whether we can use and display them to the users</strong>.</p>



<p class="wp-block-paragraph">The sample code used within this article is available <a href="https://github.com/dsibinski/DotNetReactZodApp">on GitHub</a>. We will use ASP.NET Core (C#) and React (TypeScript) apps as examples.</p>



<h3 class="wp-block-heading">Models synchronization example</h3>



<p class="wp-block-paragraph">As we saw in the beginning, a classic example is an API controller that returns a strongly-typed data:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276293" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-aspnetcontrolleraction-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="AspNetControllerAction.cs content, created by dsibinski on 02:57PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="AspNetControllerAction.cs">
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-aspnetcontrolleraction-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-smi>List</span><span class=pl-c1>&lt;</span><span class=pl-smi>UserViewModel</span><span class=pl-c1>&gt;</span> <span class=pl-en>AllUsers</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-aspnetcontrolleraction-cs-LC2" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-aspnetcontrolleraction-cs-LC3" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>var</span> <span class=pl-s1>usersViewModels</span> <span class=pl-c1>=</span> <span class=pl-s1>TestDataGenerator</span><span class=pl-kos>.</span><span class=pl-en>GetTestUsers</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-aspnetcontrolleraction-cs-LC4" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>return</span> <span class=pl-s1>usersViewModels</span><span class=pl-kos>.</span><span class=pl-en>OrderBy</span><span class=pl-kos>(</span>uvm <span class=pl-c1>=&gt;</span> <span class=pl-s1>uvm</span><span class=pl-kos>.</span><span class=pl-s1>Name</span><span class=pl-kos>)</span><span class=pl-kos>.</span><span class=pl-en>ToList</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-aspnetcontrolleraction-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-aspnetcontrolleraction-cs-LC5" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>}</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/237ce046ebdfcae6b4b7485f8c8c2006/raw/f71478548ff7ccf10fe92893a8c1aedf3ead32e3/AspNetControllerAction.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/237ce046ebdfcae6b4b7485f8c8c2006#file-aspnetcontrolleraction-cs" class="Link--inTextBlock">
          AspNetControllerAction.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The returned data type is a collection of <code>UserViewModel</code> objects. Here&#8217;s the C# definition of this type:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276303" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel.cs content, created by dsibinski on 02:58PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel.cs">
        <tr>
          <td id="file-userviewmodel-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>record</span> <span class=pl-smi>UserViewModel</span><span class=pl-kos>(</span><span class=pl-smi>Guid</span> <span class=pl-s1>Id</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>Name</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>LastName</span><span class=pl-kos>,</span> </td>
        </tr>
        <tr>
          <td id="file-userviewmodel-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel-cs-LC2" class="blob-code blob-code-inner js-file-line">    <span class=pl-smi>string</span> <span class=pl-s1>Login</span><span class=pl-kos>,</span> <span class=pl-smi>bool</span> <span class=pl-s1>IsActive</span><span class=pl-kos>,</span> <span class=pl-smi>int</span> <span class=pl-s1>LoyaltyPoints</span><span class=pl-kos>,</span> <span class=pl-smi>AddressViewModel</span><span class=pl-c1>?</span> <span class=pl-s1>Address</span> <span class=pl-c1>=</span> <span class=pl-c1>null</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/a6921cad261fb274900c991956a18f5a/raw/646dc5ed47ba33b0d663d20716697c1da6933fd3/UserViewModel.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/a6921cad261fb274900c991956a18f5a#file-userviewmodel-cs" class="Link--inTextBlock">
          UserViewModel.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Its equivalent is also defined on TypeScript side:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276311" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="userViewModel.ts content, created by dsibinski on 02:59PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="userViewModel.ts">
        <tr>
          <td id="file-userviewmodel-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel-ts-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-k>export</span> <span class=pl-k>interface</span> <span class=pl-smi>UserViewModel</span> <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel-ts-LC2" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>id</span>: <span class=pl-smi>Guid</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel-ts-LC3" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>name</span>: <span class=pl-smi>string</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel-ts-LC4" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>lastName</span>: <span class=pl-smi>string</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel-ts-LC5" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>login</span>: <span class=pl-smi>string</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel-ts-LC6" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>isActive</span>: <span class=pl-smi>boolean</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel-ts-LC7" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>loyaltyPoints</span>: <span class=pl-smi>number</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel-ts-LC8" class="blob-code blob-code-inner js-file-line">  <span class=pl-c1>address</span>: <span class=pl-smi>AddressViewModel</span> <span class=pl-c1>|</span> <span class=pl-c1>null</span><span class=pl-kos>;</span></td>
        </tr>
        <tr>
          <td id="file-userviewmodel-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel-ts-LC9" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>}</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/d03ea25ba0be55e645a0b6fe35595f47/raw/5d93472032cf0339bc34e88bb76c6be66f17241c/userViewModel.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/d03ea25ba0be55e645a0b6fe35595f47#file-userviewmodel-ts" class="Link--inTextBlock">
          userViewModel.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<h3 class="wp-block-heading">Usage in TypeScript</h3>



<p class="wp-block-paragraph">Cool. With this simple code, we can create a <code>usersService.ts</code> file and fetch our users&#8217; data from the API. Notice how we make this call strongly typed:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276316" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-usersservice-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="usersService.ts content, created by dsibinski on 03:00PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="usersService.ts">
        <tr>
          <td id="file-usersservice-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-usersservice-ts-LC1" class="blob-code blob-code-inner js-file-line">export class UsersService {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-usersservice-ts-LC2" class="blob-code blob-code-inner js-file-line">  private apiEndpoint: string;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-usersservice-ts-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-usersservice-ts-LC4" class="blob-code blob-code-inner js-file-line">  constructor() {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-usersservice-ts-LC5" class="blob-code blob-code-inner js-file-line">    this.apiEndpoint = &quot;https://localhost:7131/Users&quot;;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-usersservice-ts-LC6" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-usersservice-ts-LC7" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-usersservice-ts-LC8" class="blob-code blob-code-inner js-file-line">  getAllUsers = async (): Promise&lt;UserViewModel[]&gt; =&gt; {</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-usersservice-ts-LC9" class="blob-code blob-code-inner js-file-line">    const url = `${this.apiEndpoint}/AllUsers`;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-usersservice-ts-LC10" class="blob-code blob-code-inner js-file-line">    const response = await fetch(url);</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-usersservice-ts-LC11" class="blob-code blob-code-inner js-file-line">    const users = (await response.json()) as UserViewModel[];</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-usersservice-ts-LC12" class="blob-code blob-code-inner js-file-line">    return users;</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-usersservice-ts-LC13" class="blob-code blob-code-inner js-file-line">  };</td>
        </tr>
        <tr>
          <td id="file-usersservice-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-usersservice-ts-LC14" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/b49678cb4bb3d9ed23b9e59ecd58b595/raw/7cd1a292499e4610a6f85f20678496f1592192b8/usersService.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/b49678cb4bb3d9ed23b9e59ecd58b595#file-usersservice-ts" class="Link--inTextBlock">
          usersService.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Everything looks legit. We can use the data retrieved from the API in <code>UsersList</code> component and everything is nicely typed:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="736" height="403" data-attachment-id="4108" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/1_userslisttyped/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?fit=736%2C403&amp;ssl=1" data-orig-size="736,403" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1_UsersListTyped" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?fit=736%2C403&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?resize=736%2C403&#038;ssl=1" alt="UsersList React component" class="wp-image-4108" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?w=736&amp;ssl=1 736w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/1_UsersListTyped.png?resize=300%2C164&amp;ssl=1 300w" sizes="auto, (max-width: 736px) 100vw, 736px" /></figure>
</div>


<p class="wp-block-paragraph">The data is even perfectly displayed:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="950" height="381" data-attachment-id="4109" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/2_usersdatadispayed/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?fit=950%2C381&amp;ssl=1" data-orig-size="950,381" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2_UsersDataDispayed" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?fit=950%2C381&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=950%2C381&#038;ssl=1" alt="Table with users rendered on the web page" class="wp-image-4109" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?w=950&amp;ssl=1 950w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=300%2C120&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/2_UsersDataDispayed.png?resize=768%2C308&amp;ssl=1 768w" sizes="auto, (max-width: 950px) 100vw, 950px" /></figure>
</div>


<p class="wp-block-paragraph">So, what can go wrong here? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">The Problem &#8211; Typings&#8217; Desynchronization</h2>



<p class="wp-block-paragraph">Let&#8217;s say that a backend developer implements a requirement to rename &#8220;loyalty points&#8221; into &#8220;fidelity points&#8221;. Easy. (S)he renames <code>LoyaltyPoints</code> property in the C#&#8217;s <code>UserViewModel</code> to <code>FidelityPoints</code>.</p>



<p class="wp-block-paragraph">The new C# model looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276412" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_renamed-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel_renamed.cs content, created by dsibinski on 03:12PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel_renamed.cs">
        <tr>
          <td id="file-userviewmodel_renamed-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_renamed-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>record</span> <span class=pl-smi>UserViewModel</span><span class=pl-kos>(</span><span class=pl-smi>Guid</span> <span class=pl-s1>Id</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>Name</span><span class=pl-kos>,</span> <span class=pl-smi>string</span> <span class=pl-s1>LastName</span><span class=pl-kos>,</span> </td>
        </tr>
        <tr>
          <td id="file-userviewmodel_renamed-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_renamed-cs-LC2" class="blob-code blob-code-inner js-file-line">    <span class=pl-smi>string</span> <span class=pl-s1>Login</span><span class=pl-kos>,</span> <span class=pl-smi>bool</span> <span class=pl-s1>IsActive</span><span class=pl-kos>,</span> <span class=pl-smi>int</span> <span class=pl-s1>FidelityPoints</span><span class=pl-kos>,</span> <span class=pl-smi>AddressViewModel</span><span class=pl-c1>?</span> <span class=pl-s1>Address</span> <span class=pl-c1>=</span> <span class=pl-c1>null</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/7e0f39f3c7ffb2010000bb0ea1629701/raw/f40ac01938a57e487280fe35c4f07400d63b7cd9/UserViewModel_renamed.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/7e0f39f3c7ffb2010000bb0ea1629701#file-userviewmodel_renamed-cs" class="Link--inTextBlock">
          UserViewModel_renamed.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Nice! The backend dev is a very good programmer, so (s)he even launches the React web application to make sure that everything still works correctly and there are no errors in the dev console:</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="972" height="405" data-attachment-id="4111" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/3_userddatawithoutloyaltypointsdisplayed/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?fit=972%2C405&amp;ssl=1" data-orig-size="972,405" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3_UserdDataWithoutLoyaltyPointsDisplayed" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?fit=972%2C405&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=972%2C405&#038;ssl=1" alt="Table of users rendered on the web page with empty &quot;Loyalty points&quot; column and no errors on Chrome DevTools console" class="wp-image-4111" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?w=972&amp;ssl=1 972w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=300%2C125&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/3_UserdDataWithoutLoyaltyPointsDisplayed.png?resize=768%2C320&amp;ssl=1 768w" sizes="auto, (max-width: 972px) 100vw, 972px" /></figure>



<p class="wp-block-paragraph">After a quick look, everything looks awesome. The users list is displayed, there are no errors in the console. Apparently, these test users don&#8217;t have any loyalty points assigned &#8211; that&#8217;s why the empty values in &#8220;Loyalty points&#8221; column. What&#8217;s more, translators will update the column&#8217;s translation later. We are good! Let&#8217;s go on prod! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I guess you already know what went wrong here. <strong>API definition changed, but TypeScript didn&#8217;t inform us about that</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f614.png" alt="😔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Our <code>UserViewModel</code> still uses the old property name:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="508" height="290" data-attachment-id="4115" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/4_tsoutdateduserviewmodel/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?fit=508%2C290&amp;ssl=1" data-orig-size="508,290" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4_TSOutdatedUserViewModel" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?fit=508%2C290&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?resize=508%2C290&#038;ssl=1" alt="UserViewModel typescript type definition" class="wp-image-4115" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?w=508&amp;ssl=1 508w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/4_TSOutdatedUserViewModel.png?resize=300%2C171&amp;ssl=1 300w" sizes="auto, (max-width: 508px) 100vw, 508px" /></figure>
</div>


<p class="wp-block-paragraph">However, it still works. When rendering the <code>UsersList</code>, we simply get <code>undefined</code> in place of <code>loyaltyPoints</code>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="661" height="313" data-attachment-id="4116" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/5_tsoldpropertyundefined/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?fit=661%2C313&amp;ssl=1" data-orig-size="661,313" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5_TSOldPropertyUndefined" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?fit=661%2C313&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?resize=661%2C313&#038;ssl=1" alt="UsersList rendering at runtime. user.loyaltyPoints property is always undefined" class="wp-image-4116" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?w=661&amp;ssl=1 661w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/5_TSOldPropertyUndefined.png?resize=300%2C142&amp;ssl=1 300w" sizes="auto, (max-width: 661px) 100vw, 661px" /></figure>
</div>


<p class="wp-block-paragraph">In the end, <em>this is <a href="https://www.codejourney.net/2018/11/10-most-shocking-javascript-features-for-csharp-developers/">all JavaScript there</a></em>. What&#8217;s interesting, the renamed <code>fidelityPoints</code> property is already there at runtime:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="441" height="239" data-attachment-id="4117" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/6_newpropertypresentatjsruntime/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?fit=441%2C239&amp;ssl=1" data-orig-size="441,239" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6_NewPropertyPresentAtJsRuntime" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?fit=441%2C239&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?resize=441%2C239&#038;ssl=1" alt="At runtime we can see the new fidelityPoints property already present" class="wp-image-4117" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?w=441&amp;ssl=1 441w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/6_NewPropertyPresentAtJsRuntime.png?resize=300%2C163&amp;ssl=1 300w" sizes="auto, (max-width: 441px) 100vw, 441px" /></figure>
</div>


<p class="wp-block-paragraph">but no one cared about it <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f614.png" alt="😔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"><strong>With the current solution, we will never be informed soon enough about API models changes in our React application</strong>. In the best case, we&#8217;ll get an <code>undefiend</code> or <code>null</code> error when clicking through the app. However, it&#8217;s usually an end user who finds such problems on production. This is definitely not what we want <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f636.png" alt="😶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">We can solve this problem by typing API responses with <a href="https://github.com/colinhacks/zod">zod</a>. Let&#8217;s now see how to do that.</p>



<h2 class="wp-block-heading">The Solution &#8211; zod</h2>



<p class="wp-block-paragraph">Our remedy &#8211; <a href="https://github.com/colinhacks/zod"><code>zod</code></a> &#8211; is quite a <a href="https://www.npmjs.com/package/zod">decent npm package</a> with with ~600k weekly downloads. Its GitHub page advertises the library as <em>TypeScript-first schema validation with static type inference</em>.</p>



<p class="wp-block-paragraph">You can definitely do many things with <code>zod</code>. It can be used together with libraries like <a href="https://react-hook-form.com/">react-hook-form</a> to perform complex forms validation. However, in our case, <strong>we&#8217;ll treat <code>zod</code> as a solution for better typings in TypeScript</strong>.</p>



<h3 class="wp-block-heading">Adding zod to React app</h3>



<p class="wp-block-paragraph">First, let&#8217;s install <code>zod</code> into our React application:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
npm i zod
</pre></div>


<h3 class="wp-block-heading">First schema definition with zod</h3>



<p class="wp-block-paragraph">With <code>zod</code>, we define our types in a slightly different way. Instead of creating a <code>type</code> or <code>interface</code> directly, we first create a <em>schema</em>. In our case, we can define a <code>UserViewModelSchema</code> using <code>z.object</code> creator function:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276653" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_zodschema-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="UserViewModel_ZodSchema.ts content, created by dsibinski on 03:39PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="UserViewModel_ZodSchema.ts">
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_zodschema-ts-LC1" class="blob-code blob-code-inner js-file-line">export const UserViewModelSchema = z.object({</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_zodschema-ts-LC2" class="blob-code blob-code-inner js-file-line">  id: z.string().uuid(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel_zodschema-ts-LC3" class="blob-code blob-code-inner js-file-line">  name: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel_zodschema-ts-LC4" class="blob-code blob-code-inner js-file-line">  lastName: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel_zodschema-ts-LC5" class="blob-code blob-code-inner js-file-line">  login: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel_zodschema-ts-LC6" class="blob-code blob-code-inner js-file-line">  isActive: z.boolean(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel_zodschema-ts-LC7" class="blob-code blob-code-inner js-file-line">  loyaltyPoints: z.number(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel_zodschema-ts-LC8" class="blob-code blob-code-inner js-file-line">  address: AddressViewModelSchema.nullable(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zodschema-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel_zodschema-ts-LC9" class="blob-code blob-code-inner js-file-line">});</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/9c7759dff996babccf1b14da276d76c8/raw/959d8bf640a1f20dc10b7975c7a8fa40e62392d5/UserViewModel_ZodSchema.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/9c7759dff996babccf1b14da276d76c8#file-userviewmodel_zodschema-ts" class="Link--inTextBlock">
          UserViewModel_ZodSchema.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Few interesting parts here:</p>



<ul class="wp-block-list"><li><em>Line 2</em>: notice how <code>zod</code> helps us to define types like <code>Guid</code> with built-in schemas like <code>uuid()</code></li><li><em>Line 8</em>: first, I used <code>AddressViewModelSchema</code> here. This is a custom schema of an <code>AddressViewModel</code> object, which is another type used internally in <code>UserViewModel</code>. You can use such custom schemas in other schemas. Also notice the <code>nullable()</code> call here, which makes the <code>address</code> property nullable</li></ul>



<p class="wp-block-paragraph">First step done &#8211; we have our <code>UserViewModelSchema</code>. But can we use it instead of <code>UserViewModel</code> type? Not really. Schema is used for validation purposes only. We still need the <code>UserViewModel</code> TypeScript&#8217;s type. </p>



<h3 class="wp-block-heading">Inferring type from zod&#8217;s schema</h3>



<p class="wp-block-paragraph">Fortunately, <code>zod</code> comes with a handy <code>z.infer</code> function that allows us to <em>infer</em> the type from the schema.</p>



<p class="wp-block-paragraph">Finally, the <code>userViewModel.ts</code> file looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276693" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-userviewmodel_zod-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="userViewModel_zod.ts content, created by dsibinski on 03:43PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="userViewModel_zod.ts">
        <tr>
          <td id="file-userviewmodel_zod-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-userviewmodel_zod-ts-LC1" class="blob-code blob-code-inner js-file-line">import { z } from &quot;zod&quot;;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-userviewmodel_zod-ts-LC2" class="blob-code blob-code-inner js-file-line">import { AddressViewModelSchema } from &quot;./addressViewModel&quot;;</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-userviewmodel_zod-ts-LC3" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-userviewmodel_zod-ts-LC4" class="blob-code blob-code-inner js-file-line">export const UserViewModelSchema = z.object({</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-userviewmodel_zod-ts-LC5" class="blob-code blob-code-inner js-file-line">  id: z.string().uuid(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-userviewmodel_zod-ts-LC6" class="blob-code blob-code-inner js-file-line">  name: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-userviewmodel_zod-ts-LC7" class="blob-code blob-code-inner js-file-line">  lastName: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-userviewmodel_zod-ts-LC8" class="blob-code blob-code-inner js-file-line">  login: z.string(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-userviewmodel_zod-ts-LC9" class="blob-code blob-code-inner js-file-line">  isActive: z.boolean(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-userviewmodel_zod-ts-LC10" class="blob-code blob-code-inner js-file-line">  loyaltyPoints: z.number(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-userviewmodel_zod-ts-LC11" class="blob-code blob-code-inner js-file-line">  address: AddressViewModelSchema.nullable(),</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-userviewmodel_zod-ts-LC12" class="blob-code blob-code-inner js-file-line">});</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-userviewmodel_zod-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-userviewmodel_zod-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-userviewmodel_zod-ts-LC14" class="blob-code blob-code-inner js-file-line">export type UserViewModel = z.infer&lt;typeof UserViewModelSchema&gt;;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/64cb91fade703c4bbf6ade4c6ad84d19/raw/d45af9863a80557b643b3b04c3440287c20a923b/userViewModel_zod.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/64cb91fade703c4bbf6ade4c6ad84d19#file-userviewmodel_zod-ts" class="Link--inTextBlock">
          userViewModel_zod.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">We can use the exported <code>UserViewModel</code> type as previously used type. It&#8217;s an equivalent, inferred from <code>UserViewModelSchema</code>.</p>



<h3 class="wp-block-heading">Validating API responses with zod schema</h3>



<p class="wp-block-paragraph">One last step is to make use of <code>UserViewModelSchema</code>. Let&#8217;s modify the <code>getAllUsers</code> function from <code>usersService</code> to validate the data received from the API against our schema:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist117276973" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-getallusers_with_zod-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="getAllUsers_with_zod.ts content, created by dsibinski on 04:13PM on July 09, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="getAllUsers_with_zod.ts">
        <tr>
          <td id="file-getallusers_with_zod-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-getallusers_with_zod-ts-LC1" class="blob-code blob-code-inner js-file-line">getAllUsers = async (): Promise&lt;UserViewModel[]&gt; =&gt; {</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-getallusers_with_zod-ts-LC2" class="blob-code blob-code-inner js-file-line">  const url = `${this.apiEndpoint}/AllUsers`;</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-getallusers_with_zod-ts-LC3" class="blob-code blob-code-inner js-file-line">  const response = await fetch(url);</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-getallusers_with_zod-ts-LC4" class="blob-code blob-code-inner js-file-line">  const usersJson = await response.json();</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-getallusers_with_zod-ts-LC5" class="blob-code blob-code-inner js-file-line">  const users = z.array(UserViewModelSchema).parse(usersJson);</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-getallusers_with_zod-ts-LC6" class="blob-code blob-code-inner js-file-line">  return users;</td>
        </tr>
        <tr>
          <td id="file-getallusers_with_zod-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-getallusers_with_zod-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ac10bdf2e256f549939d6eeed68067aa/raw/d996f3ee73f81ada41ee15ac3fadf14064992acc/getAllUsers_with_zod.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/ac10bdf2e256f549939d6eeed68067aa#file-getallusers_with_zod-ts" class="Link--inTextBlock">
          getAllUsers_with_zod.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Notice the usage of <code>z.array</code>. This function call tells <code>zod</code> to validate an array of objects meeting the rules defined by <code>UserViewModelSchema</code>, not a single object.</p>



<p class="wp-block-paragraph">Now, let&#8217;s run our React app and see what happens when we click the &#8220;Fetch users&#8221; button:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="651" height="592" data-attachment-id="4121" data-permalink="https://www.codejourney.net/typing-api-responses-with-zod/7_zodschemavalidationerror/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?fit=651%2C592&amp;ssl=1" data-orig-size="651,592" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7_ZodSchemaValidationError" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?fit=651%2C592&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?resize=651%2C592&#038;ssl=1" alt="zod throws schema validation error on Chrome dev tools console" class="wp-image-4121" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?w=651&amp;ssl=1 651w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/07/7_ZodSchemaValidationError.png?resize=300%2C273&amp;ssl=1 300w" sizes="auto, (max-width: 651px) 100vw, 651px" /></figure>
</div>


<p class="wp-block-paragraph">This is awesome! Exactly what we wanted &#8211; a <strong>schema validation error for API response</strong>. Notice how the <strong>error message precisely points to the missing (or wrong, in other cases) property.</strong> It tells us we expected a <code>number</code> called <code>loyaltyPoints</code>, but instead we received <code>undefined</code>. The reason for this error message is that the <code>loyaltyPoints</code> field is <code>Required</code> in our schema.</p>



<p class="wp-block-paragraph">After renaming <code>loyaltyPoints</code> to <code>fidelityPoints</code> in <code>UserViewModelSchema</code> and updating the <code>UsersList</code> component accordingly, everything works fine again. </p>



<p class="wp-block-paragraph">We are now fully typed and prepared for the future, in case an issue with desynchronization of frontend and backend typings happens again <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">Today, we&#8217;ve seen how typing API responses with <code>zod</code> can help us detect frontend and backend models desynchronization. Schema validation throws errors when the data doesn&#8217;t match its expected shape. </p>



<p class="wp-block-paragraph">Remember that <code>zod</code> is an extended library with many options. I recommend <a href="https://github.com/colinhacks/zod">exploring them</a> on your own. An interesting feature we didn&#8217;t cover in this article is <a href="https://github.com/colinhacks/zod#strict">strict mode</a>, which doesn&#8217;t allow additional fields not present in the schema definition when validating the data object. </p>



<p class="wp-block-paragraph">The open question remains whether to use schema validation on production. One could think that it&#8217;s better to not throw any validation errors, because <em>JavaScript may just work</em>. However, I think that throwing an error is always better than <em>silently</em> letting things through. An error lets programmers, automated tests or manual testers to detect the issue before the end user does <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can explore the complete code presented in this article <a href="https://github.com/dsibinski/DotNetReactZodApp">here</a>.</p>
<p>The post <a href="https://www.codejourney.net/typing-api-responses-with-zod/">Typing API Responses With Zod</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/typing-api-responses-with-zod/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4093</post-id>	</item>
		<item>
		<title>Write Test Progress To The Console With NUnit</title>
		<link>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/</link>
					<comments>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sun, 19 Jun 2022 13:07:28 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[nunit]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4070</guid>

					<description><![CDATA[<p>I recently needed to write test progress to the console with NUnit. The task we want to solve here is basically the TODO part of this snippet: The title picture of this article shows the end result. If you want to know the solution, keep reading 🙂 Context The context of this need is very&#8230;</p>
<p>The post <a href="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/">Write Test Progress To The Console With NUnit</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I recently needed to write test progress to the console with NUnit. The task we want to solve here is basically the <em>TODO</em> part of this snippet:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist116902181" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-nunit_test_progress_todo-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="NUnit_test_progress_todo.cs content, created by dsibinski on 04:54AM on June 19, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="NUnit_test_progress_todo.cs">
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-nunit_test_progress_todo-cs-LC1" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>[</span><span class=pl-c1>TestFixture</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-nunit_test_progress_todo-cs-LC2" class="blob-code blob-code-inner js-file-line"><span class=pl-k>public</span> <span class=pl-k>class</span> <span class=pl-smi>MyTests</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-nunit_test_progress_todo-cs-LC3" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-nunit_test_progress_todo-cs-LC4" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>[</span><span class=pl-c1>Test</span><span class=pl-kos>]</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-nunit_test_progress_todo-cs-LC5" class="blob-code blob-code-inner js-file-line">    <span class=pl-k>public</span> <span class=pl-smi>void</span> <span class=pl-en>SampleTest</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-nunit_test_progress_todo-cs-LC6" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-nunit_test_progress_todo-cs-LC7" class="blob-code blob-code-inner js-file-line">        <span class=pl-c>// some operations here, like starting a server for tests in-memory&#8230;</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-nunit_test_progress_todo-cs-LC8" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-nunit_test_progress_todo-cs-LC9" class="blob-code blob-code-inner js-file-line">        <span class=pl-c>// TODO: inform the &#39;user&#39; (the one who runs the test) that the server is already running</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-nunit_test_progress_todo-cs-LC10" class="blob-code blob-code-inner js-file-line">        <span class=pl-k>while</span> <span class=pl-kos>(</span><span class=pl-c1>true</span><span class=pl-kos>)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-nunit_test_progress_todo-cs-LC11" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>{</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-nunit_test_progress_todo-cs-LC12" class="blob-code blob-code-inner js-file-line">            <span class=pl-c>// keep it running on purpose (e.g. for E2E tests)</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-nunit_test_progress_todo-cs-LC13" class="blob-code blob-code-inner js-file-line">        <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-nunit_test_progress_todo-cs-LC14" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-nunit_test_progress_todo-cs-LC15" class="blob-code blob-code-inner js-file-line">    <span class=pl-kos>}</span></td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress_todo-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-nunit_test_progress_todo-cs-LC16" class="blob-code blob-code-inner js-file-line"><span class=pl-kos>}</span></td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/419247cf91eaa4bd67f820a9af5e0dd9/raw/1f387ac42e1bf490b1531fc7808de21fe2fe6aff/NUnit_test_progress_todo.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/419247cf91eaa4bd67f820a9af5e0dd9#file-nunit_test_progress_todo-cs" class="Link--inTextBlock">
          NUnit_test_progress_todo.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">The title picture of this article shows the end result. If you want to know the solution, keep reading <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4070"></span>



<h2 class="wp-block-heading">Context</h2>



<p class="wp-block-paragraph">The context of this need is very simple. I have a unit test in which I want to perform some operations and keep the test running indefinitely afterwards. The use case might be instantiation of an <a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.testhost.testserver?view=aspnetcore-6.0">in-memory test server</a>. After that, I want to inform the user (programmer or the one running the test) that the server is up and running. I want to do that <strong>before the test finishes</strong>. In other words: <strong>I want to write the test&#8217;s output while it&#8217;s still running</strong>. </p>



<p class="wp-block-paragraph">In my case, I was running two .NET Core apps in-memory. The backend server app and the ASP.NET Core web application. In the process, the web app got its IP address assigned dynamically. Meaning that the IP was different with each test run. This particular test was used to run the app in-memory and let the user manually use the application. It means the user must know the IP/URL of the in-memory web app. That&#8217;s why I needed to output the dynamic IP address into the NUnit test output <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Solution</h2>



<p class="wp-block-paragraph">The solution to write test progress to the console with NUnit is very simple. To do that, use <code>TestContext.Progress.WriteLine(string)</code> method from <code>NUnit.Framework</code> namespace:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist116902272" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-nunit_test_progress-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="NUnit_test_progress.cs content, created by dsibinski on 05:05AM on June 19, 2022."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="NUnit_test_progress.cs">
        <tr>
          <td id="file-nunit_test_progress-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-nunit_test_progress-cs-LC1" class="blob-code blob-code-inner js-file-line">[TestFixture]</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-nunit_test_progress-cs-LC2" class="blob-code blob-code-inner js-file-line">public class MyTests</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-nunit_test_progress-cs-LC3" class="blob-code blob-code-inner js-file-line">{</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-nunit_test_progress-cs-LC4" class="blob-code blob-code-inner js-file-line">    [Test]</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-nunit_test_progress-cs-LC5" class="blob-code blob-code-inner js-file-line">    public void SampleTest()</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-nunit_test_progress-cs-LC6" class="blob-code blob-code-inner js-file-line">    {</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-nunit_test_progress-cs-LC7" class="blob-code blob-code-inner js-file-line">        // some operations here, like starting a server for tests in-memory&#8230;</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-nunit_test_progress-cs-LC8" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-nunit_test_progress-cs-LC9" class="blob-code blob-code-inner js-file-line">        TestContext.Progress.WriteLine(&quot;The server is running now! You can reach it on https://localhost:8067/&quot;);</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-nunit_test_progress-cs-LC10" class="blob-code blob-code-inner js-file-line">        while (true)</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-nunit_test_progress-cs-LC11" class="blob-code blob-code-inner js-file-line">        {</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-nunit_test_progress-cs-LC12" class="blob-code blob-code-inner js-file-line">            // keep it running on purpose (e.g. for E2E tests)</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-nunit_test_progress-cs-LC13" class="blob-code blob-code-inner js-file-line">        }</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-nunit_test_progress-cs-LC14" class="blob-code blob-code-inner js-file-line">        </td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-nunit_test_progress-cs-LC15" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-nunit_test_progress-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-nunit_test_progress-cs-LC16" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/03221c21614c48cef6fdbbd5e11accb4/raw/1880d0e1f47cb145c600d96e5f1d392bf5728028/NUnit_test_progress.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/03221c21614c48cef6fdbbd5e11accb4#file-nunit_test_progress-cs" class="Link--inTextBlock">
          NUnit_test_progress.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">And that&#8217;s it! I&#8217;m publishing this simple solution, because it took me some time to find <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">I previously tried with <code>TestContext.Out.WriteLine</code>, <code>System.Diagnostics.Trace.WriteLine</code> and <code>System.Console.WriteLine</code>, but all of them output the text <em>after </em>the test finishes.</p>



<p class="wp-block-paragraph">Finally, you can also run the test from cmd using <code>dotnet test</code>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="189" data-attachment-id="4081" data-permalink="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/nunit_cmd_console_progress/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?fit=1119%2C206&amp;ssl=1" data-orig-size="1119,206" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NUnit_cmd_console_progress" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?fit=1024%2C189&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=1024%2C189&#038;ssl=1" alt="" class="wp-image-4081" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=1024%2C189&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=300%2C55&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?resize=768%2C141&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/06/NUnit_cmd_console_progress.png?w=1119&amp;ssl=1 1119w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p class="wp-block-paragraph">Hope it&#8217;s useful!</p>
<p>The post <a href="https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/">Write Test Progress To The Console With NUnit</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/write-test-progress-to-the-console-with-nunit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4070</post-id>	</item>
		<item>
		<title>How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</title>
		<link>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/</link>
					<comments>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 17 May 2022 05:32:15 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[microsoft azure]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4036</guid>

					<description><![CDATA[<p>I recently deployed my .NET 6 application to Microsoft Azure. The app uses NHibernate for working with SQL Server database. After some time, I started getting an unhandled exception when opening the application: The database is not currently available was very interesting to me. I struggled a bit with solving that, so if you want&#8230;</p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I recently deployed my .NET 6 application to Microsoft Azure. The app uses <a href="https://nhibernate.info/">NHibernate</a> for working with SQL Server database. After some time, I started getting an unhandled exception when opening the application:</p>



<pre class="wp-block-code"><code>NHibernate.Exceptions.GenericADOException: could not load an entity: 
...
 ---&gt; Microsoft.Data.SqlClient.SqlException (0x80131904): <strong>Database 'myappdb' on server 'myapp.database.windows.net' is not currently available</strong>.  Please retry the connection later.  If the problem persists, contact customer support, and provide them the session tracing ID of '{EB501CF2-2F21-4E28-9042-2B83EEE57B91}'.</code></pre>



<p class="wp-block-paragraph">The <em>database is</em> <em>not currently available </em>was very interesting to me. I struggled a bit with solving that, so if you want to know how I did it &#8211; continue reading <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4036"></span>



<h2 class="wp-block-heading">The problem</h2>



<p class="wp-block-paragraph">My .NET 6 app is an <a href="https://azure.microsoft.com/en-us/services/app-service/">Azure App Service</a>, and it uses SQL Server database. Quite standard Azure stuff.</p>



<p class="wp-block-paragraph">The issue was that when opening the ASP.NET web app after some time of inactivity, there was an HTTP 500 error. When I checked the logs, the full error looked as follows:</p>



<pre class="wp-block-code"><code><strong>NHibernate.Exceptions.GenericADOException: could not load an entity</strong>: &#91;MyApp.Infrastructure.DomainObjects.ApplicationUser#37931c5a376748d7a49f215ca30283a2]&#91;SQL: SELECT applicatio0_.applicationuser_key as id1_3_0_, applicatio0_1_.UserName as username2_3_0_, applicatio0_1_.NormalizedUserName as normalizedusername3_3_0_, applicatio0_1_.Email as email4_3_0_, applicatio0_1_.NormalizedEmail as normalizedemail5_3_0_, applicatio0_1_.EmailConfirmed as emailconfirmed6_3_0_, applicatio0_1_.PhoneNumber as phonenumber7_3_0_, applicatio0_1_.PhoneNumberConfirmed as phonenumberconfirmed8_3_0_, applicatio0_1_.LockoutEnabled as lockoutenabled9_3_0_, applicatio0_1_.LockoutEnd as lockoutend10_3_0_, applicatio0_1_.AccessFailedCount as accessfailedcount11_3_0_, applicatio0_1_.ConcurrencyStamp as concurrencystamp12_3_0_, applicatio0_1_.PasswordHash as passwordhash13_3_0_, applicatio0_1_.TwoFactorEnabled as twofactorenabled14_3_0_, applicatio0_1_.SecurityStamp as securitystamp15_3_0_ FROM ApplicationUsers applicatio0_ inner join dbo.AspNetUsers applicatio0_1_ on applicatio0_.applicationuser_key=applicatio0_1_.Id WHERE applicatio0_.applicationuser_key=?]
 ---&gt; Microsoft.Data.SqlClient.SqlException (0x80131904): <strong>Database 'myappdb' on server 'myapp.database.windows.net' is not currently available</strong>.  Please retry the connection later.  If the problem persists, contact customer support, and provide them the session tracing ID of '{EB501CF2-2F21-4E28-2342-2B836E35E891}'.
   at Microsoft.Data.ProviderBase.DbConnectionPool.CheckPoolBlockingPeriod(Exception e)</code></pre>



<p class="wp-block-paragraph">There were two characteristics of this error:</p>



<ul class="wp-block-list"><li>it always appeared after some time of not using the web app</li><li>I never reproduced it locally</li></ul>



<p class="wp-block-paragraph">So it must have been something wrong with Azure.</p>



<h2 class="wp-block-heading">Transient issues in Azure databases</h2>



<p class="wp-block-paragraph">First thing I did, obviously, was checking Azure App Service logs. This is what I found:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="288" data-attachment-id="4053" data-permalink="https://www.codejourney.net/azure_database_transient_problems/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?fit=1482%2C417&amp;ssl=1" data-orig-size="1482,417" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_database_transient_problems" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?fit=1024%2C288&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=1024%2C288&#038;ssl=1" alt="Error log when database is not currently available error occured in Azure" class="wp-image-4053" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=1024%2C288&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=300%2C84&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?resize=768%2C216&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_database_transient_problems.png?w=1482&amp;ssl=1 1482w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">The first recommended step got me curious. <em>To reduce the impact of connection issues caused by future reconfiguration, <strong>please implement retry logic in your code</strong></em>.</p>



<p class="wp-block-paragraph">So I started reading. There&#8217;s even <a href="https://docs.microsoft.com/en-us/aspnet/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/transient-fault-handling">official Microsoft documentation for that</a>. It basically says that <em>in the cloud environment you&#8217;ll find that failed and dropped database connections happen periodically.</em></p>



<p class="wp-block-paragraph">I must admit it seemed quite new to me. However, I started digging into that. I used <a href="https://github.com/App-vNext/Polly">Polly</a> to implement the retry logic in my app. I found few places where there was an NHibernate query for fetching users executed and wrapped it into the retry policy.</p>



<p class="wp-block-paragraph">Nothing worked. I was still getting the error. Then, after some talks with my coworkers, we found the real reason behind that&#8230;</p>



<h2 class="wp-block-heading">Solution: Azure database tier</h2>



<p class="wp-block-paragraph">When talking about the issue with my teammates, someone mentioned that the databases in Azure are <em>serverless</em> by default.</p>



<p class="wp-block-paragraph">I logged into the <a href="https://portal.azure.com/">Azure Portal</a> and checked the &#8220;Compute + storage&#8221; settings my SQL database my app used:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="382" data-attachment-id="4055" data-permalink="https://www.codejourney.net/azure_tier_settings_serverless/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?fit=1193%2C445&amp;ssl=1" data-orig-size="1193,445" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_tier_settings_serverless" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?fit=1024%2C382&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=1024%2C382&#038;ssl=1" alt="Azure Portal and Service and compute tier settings of SQL Database set to General Purpose. Reason for database is not currently available error" class="wp-image-4055" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=1024%2C382&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=300%2C112&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?resize=768%2C286&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_serverless.png?w=1193&amp;ssl=1 1193w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">Indeed, the tier selected was &#8220;General purpose (Scalable compute and storage options)&#8221; with &#8220;Serverless&#8221; compute tier selected.</p>



<p class="wp-block-paragraph">I changed it to &#8220;Basic (For less demanding workloads)&#8221;:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="507" data-attachment-id="4056" data-permalink="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/azure_tier_settings_basic/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?fit=1188%2C588&amp;ssl=1" data-orig-size="1188,588" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Azure_tier_settings_basic" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?fit=1024%2C507&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=1024%2C507&#038;ssl=1" alt="Azure Portal and tier of the SQL database changed to Basic. It made database is not currently available error disappear" class="wp-image-4056" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=1024%2C507&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=300%2C148&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?resize=768%2C380&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2022/05/Azure_tier_settings_basic.png?w=1188&amp;ssl=1 1188w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p class="wp-block-paragraph">and&#8230; it worked <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f92f.png" alt="🤯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> All errors saying that the database is not currently available disappeared. I also removed all Polly-related code for retry policies.</p>



<h2 class="wp-block-heading">A little explanation</h2>



<p class="wp-block-paragraph">Why do serverless databases in Azure behave like that?</p>



<p class="wp-block-paragraph">I finally found this explanation in the <a href="https://docs.microsoft.com/en-us/azure/azure-sql/database/serverless-tier-overview?view=azuresql">Microsoft documentation</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>If a serverless database is paused, then <strong>the first login will resume the database and return an error stating that the database is unavailable with error code 40613</strong>. Once the database is resumed, the login must be retried to establish connectivity</p></blockquote>



<p class="wp-block-paragraph">That blew my mind! It means that the <em>database is not currently available</em> exception is expected. There&#8217;s also another part there:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Database clients with connection retry logic should not need to be modified. For connection retry logic options that are built-in to the SqlClient driver, see&nbsp;<a href="https://docs.microsoft.com/en-us/sql/connect/ado-net/configurable-retry-logic">configurable retry logic in SqlClient</a>.</p></blockquote>



<p class="wp-block-paragraph">Apparently, users of ORMs like Entity Framework <a href="https://docs.microsoft.com/en-us/ef/ef6/fundamentals/connection-resiliency/retry-logic">should not have to worry about those issues</a>. Unfortunately, NHibernate doesn&#8217;t have such built-in transient errors retry logic. That&#8217;s why I experienced this particular issue and couldn&#8217;t find any straightforward solution online. Simply not many people (if anyone at all? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" />) experienced this before.</p>



<p class="wp-block-paragraph">If you want even more details and context, check out this article: <a href="https://kohera.be/azure-cloud/should-i-use-serverless-for-all-my-azure-sql-databases/">SHOULD I USE SERVERLESS FOR ALL MY AZURE SQL DATABASES?</a></p>



<h2 class="wp-block-heading">What if I want to use serverless Azure database?</h2>



<p class="wp-block-paragraph">Well&#8230; if you really want to use the serverless features of Azure, you might be struggling with NHibernate. As I mentioned, apparently there&#8217;s no built-in transient failures retry mechanism in the ORM. There&#8217;s one promising solution <a href="https://github.com/MRCollective/NHibernate.SqlAzure">here</a>. However, currently it&#8217;s build for NHibernate 3.3.1.4000, so it doesn&#8217;t work with the current version. There&#8217;s a <a href="https://github.com/MRCollective/NHibernate.SqlAzure/pull/37">Pull Request</a> and an <a href="https://github.com/MRCollective/NHibernate.SqlAzure/issues/32">issue</a> opened for upgrading it to the newest version and .NET 6/7. Let&#8217;s hope it is done soon.</p>



<p class="wp-block-paragraph">Otherwise, you can try using <a href="https://www.codejourney.net/2022/05/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">Polly</a> as I did initially. However, I didn&#8217;t manage to make fully working.</p>



<p class="wp-block-paragraph">If you have any other idea or solution &#8211; let us know in the comments below.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">I hope this article saves you some hours of debugging, so you can quickly solve this <em>database is not currently available</em> error in Azure. I wish I found this article on another website few weeks ago <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/">How To Fix SqlException Database Is Not Currently Available On Azure (0x80131904)</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/how-to-fix-sqlexception-database-is-not-currently-available-on-azure-0x80131904/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4036</post-id>	</item>
		<item>
		<title>Is It Worth Migrating to TypeScript?</title>
		<link>https://www.codejourney.net/is-it-worth-migrating-to-typescript/</link>
					<comments>https://www.codejourney.net/is-it-worth-migrating-to-typescript/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Sat, 29 Aug 2020 11:03:05 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ts]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[typescript migration]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3840</guid>

					<description><![CDATA[<p>Choosing migration strategy Bright side of migrating to TypeScript If you are a JavaScript developer, the best advice I can give you is to start using TypeScript 🙂 In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript. Types &#8220;for free&#8221; As soon as we changed our transpiler&#8230;</p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>For the past year I&#8217;ve been working on a JavaScript project for my client. We have a mid-size web application. We use React as the web development framework. Few months ago we decided to start migrating to TypeScript.</p>
<p>Today I can say that <strong>it was the best decision we could make</strong>. TypeScript makes working with JavaScript, which is sometimes <a href="https://www.codejourney.net/2018/11/10-most-shocking-javascript-features-for-csharp-developers/" target="_blank" rel="noopener noreferrer">surprising and quite hard to understand</a>, so much better experience. However, there were some challenges on this journey. If you want to know what issues we met and how we solved them, but also what huge advantages TypeScript gave us &#8211; read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><em>I will not discuss TypeScript itself in this article. This is a pure recap of challenges and the experience I gained when migrating to TypeScript.</em></p>



<span id="more-3840"></span>



<h2 class="wp-block-heading">Choosing migration strategy</h2>



<p>Before starting migrating to TypeScript, we had to choose the best strategy for this process. There were two possibilities we considered: <strong>migrating the whole JavaScript codebase to TypeScript at once</strong> or <strong>switching to TypeScript compiler and migrating part-by-part</strong>.</p>
<p>For those who are not familiar with TypeScript &#8211; it is a superset of JavaScript which adds typing information to your JS code. It means that <strong>every JavaScript code is also a valid TypeScript code</strong>. When compiling TypeScript code, TS compiler removes the typing data and outputs readable, vanilla JavaScript code ready to be executed.</p>
<p>Migrating the whole codebase to TypeScript would mean to change all files extensions to TypeScript ones: <em>.js</em> to <em>.ts</em> and <em>.jsx</em> to <em>.tsx</em>. It would also mean that TypeScript compiler starts checking types in those files. This approach is doable, but &#8211; depending on the size of your project &#8211; can take a long time. During migration the code would be frozen until you fully migrate the project. Also, for TypeScript beginners, it could be a bit frustrating having to type everything at once or use some tricks to tell TypeScript to ignore checking types in many cases (because the type is not known at this stage, or we want to do it later etc.).</p>
<p>Because of that, <strong>we decided to migrate part-by-part, having JavaScript and TypeScript files at the same time</strong>. It is possible thanks to enabling <a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html" target="_blank" rel="noopener noreferrer"><em>allowJs&nbsp;</em>TS compiler option</a>. It means that TypeScript will compile both TS and JS files. Such approach allows the coexistence of old JS code with the new TS parts. It also allows moving only chosen parts of the application to TypeScript at the beginning and come back to the others later.</p>
<p>In our web application the biggest JS files have few thousand lines of code. Some of this legacy code still didn&#8217;t use React, but <a href="https://backbonejs.org/" target="_blank" rel="noopener noreferrer">Backbone</a> as their framework. We didn&#8217;t want to touch these oldest files in the beginning. Instead, <strong>we moved few recently written functionalities to TypeScript straightaway and decided to implement everything new in TS as well</strong>.</p>



<h2 class="wp-block-heading">Bright side of migrating to TypeScript</h2>



<p class="wp-block-paragraph">If you are a JavaScript developer, the best advice I can give you is to start using TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> In this section I&#8217;m describing what positively surprised me since the beginning of starting to use TypeScript.</p>



<h3 class="wp-block-heading">Types &#8220;for free&#8221;</h3>



<p class="wp-block-paragraph">As soon as we changed our transpiler from <em>babel-loader</em> to <em>ts-loader, </em>I wanted to know how we can get typing information for already-installed npm packages. It turns out that <strong>for 98% of the packages we used there&#8217;s already a typing information available</strong> as a separate npm package. </p>



<p class="wp-block-paragraph">In most cases if you have a npm package called <em>abc</em> there&#8217;s a typing package available called <em>@types/abc</em>. I explored our <em>package.json </em>and for each package listed there I just executed <em>npm install @types/package-name</em>. 2 or 3 older or not-so-popular packages didn&#8217;t have types definitions available, but for the rest we got types for free, without having to type anything ourselves. This was a first, very nice surprise <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">You can find more information about TypeScript types definition packages, as well as contribute one yourself, <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h3 class="wp-block-heading">All new code is typed</h3>



<p class="wp-block-paragraph">As I wrote before, every new feature we&#8217;ve added since the migration is written in TypeScript. Thanks to that, <strong>all n</strong>ew code we write <strong>is strongly typed</strong>. What&#8217;s remarkable here is that it required almost no effort. We just switched the compiler to TS (with a small struggle with webpack configuration, about which you can read below) and suddenly got into typed world for every new feature we implement. Quite impressive, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">JS-TS friendship</h3>



<p class="wp-block-paragraph">Coexistence and friendship between JavaScript and TypeScript is HUGE. <strong>These two creatures are not enemies &#8211; they are best friends</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /> We&#8217;ve already gone through many scenarios when we needed to use something written in TS in a JS file and otherwise. It turns out that all of these scenarios are manageable. Sometimes you need to import something differently (for example using <em>require</em> instead of <em>import</em>), but it&#8217;s all possible. We found it super easy to write new features or even add parts of new features to already-existing JS code, writing everything in TypeScript.</p>



<p class="wp-block-paragraph">We also rewrote some JS files that were used from multiple places in the app to TypeScript. As an example of JS-TS coexistence, I&#8217;m presenting below the potential <em>.ts</em> source code you might have. It contains both old, legacy JS code when we used <em>module.exports</em> and <em>prototype</em> to expose various services for data fetching, as well as a brand-new, nicely-exported TypeScript class:</p>



<p class="wp-block-paragraph"><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105109386" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-services-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="services.ts content, created by dsibinski on 08:09AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="services.ts">
        <tr>
          <td id="file-services-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-services-ts-LC1" class="blob-code blob-code-inner js-file-line">module.exports.UsersService = function (url) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-services-ts-LC2" class="blob-code blob-code-inner js-file-line">  // &#8230; UsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-services-ts-LC3" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-services-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-services-ts-LC5" class="blob-code blob-code-inner js-file-line">module.exports.UsersService.prototype.getUser = function (id) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-services-ts-LC6" class="blob-code blob-code-inner js-file-line">  // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-services-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
        <tr>
          <td id="file-services-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-services-ts-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-services-ts-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-services-ts-LC10" class="blob-code blob-code-inner js-file-line">export class NewUsersService {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-services-ts-LC11" class="blob-code blob-code-inner js-file-line">  url: string;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-services-ts-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-services-ts-LC13" class="blob-code blob-code-inner js-file-line">  constructor(url: string) {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-services-ts-LC14" class="blob-code blob-code-inner js-file-line">    // &#8230; NewUsersService init code &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-services-ts-LC15" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-services-ts-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-services-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-services-ts-LC17" class="blob-code blob-code-inner js-file-line">  getUser(id: number): JQuery.Promise&lt;UserViewModel, any, any&gt; {</td>
        </tr>
        <tr>
          <td id="file-services-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-services-ts-LC18" class="blob-code blob-code-inner js-file-line">    // &#8230; code to get active user by id &#8230;</td>
        </tr>
        <tr>
          <td id="file-services-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-services-ts-LC19" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-services-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-services-ts-LC20" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740/raw/504b504a930a8262f334017f8aeddc675e3692bf/services.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/fceb3650f2121640a5e32a78ec3dc740#file-services-ts" class="Link--inTextBlock">
          services.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
 </p>



<p class="wp-block-paragraph">Such code can of course be in separate files, but it only shows how good TS and JS can coexist together. You can keep your old code working, while implementing anything new in TypeScript.</p>



<h3 class="wp-block-heading">Flexibility in partial migrating to TypeScript</h3>



<p class="wp-block-paragraph">It turns out that choosing to partially move our web project to TypeScript was a great decision. The team wouldn&#8217;t be so happy and enthusiastic about TS if we told them to move legacy Backbone code to TypeScript. Instead, we gave them a nice tool which can be used for all new stuff. Also, if someone likes the idea and wants to move already-existing JS file to TS, he or she is welcome to do so. </p>



<p class="wp-block-paragraph">That&#8217;s how <strong>we are still migrating our project to TypeScript, without any hustle and frustration</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Wisdom of TypeScript</h3>



<p class="wp-block-paragraph">I&#8217;m positively surprised by TypeScript almost every day. At some point I get to the issue that seems hard to be solved or quite non-standard. Then I find a solution online and <strong>it makes me really impressed about the job <a href="https://github.com/microsoft/TypeScript" target="_blank" rel="noreferrer noopener">the community and Microsoft has been doing</a> around the language</strong>. </p>



<p class="wp-block-paragraph">These are sometimes small, but smart things. Recently we got surprised by <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a>, which lets you get names of the allowed properties of your type. Generally <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html" target="_blank" rel="noreferrer noopener">the typing system</a> is really advanced and impressive. For some it can be a disadvantage, but I think it gives an enormous flexibility. </p>



<p class="wp-block-paragraph">This is somehow the JavaScript you-can-do-whatever-you-want philosophy smuggled into TypeScript <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f601.png" alt="😁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> But in a much smarter way. I&#8217;m sure that when you start working with TypeScript you&#8217;ll get what I mean by its wisdom <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading">Small effort, huge benefits</h3>



<p>Last, but not least, I must admit that <strong>migrating to TypeScript was quite an easy and smooth process. The value for the effort is huge</strong>. You get a typed world with very little work.</p>



<h2 class="wp-block-heading">Migrating to TypeScript struggles</h2>



<p class="wp-block-paragraph">During the migration process we met few difficulties. Some of them we managed to solve fully or partially. If you have any better ideas on these things, feel free to let me know in the comments.</p>



<h3 class="wp-block-heading">Complexity of webpack configuration</h3>



<p class="wp-block-paragraph">When switching to TypeScript we had few issues with <a href="https://webpack.js.org/" target="_blank" rel="noreferrer noopener">webpack</a> configuration. We have used <a href="https://github.com/babel/babel-loader" target="_blank" rel="noreferrer noopener"><em>babel-loader</em></a> before for transpiling JavaScript and initially we wanted to keep it in the TS compilation process. We first tried to keep <em>babel-loader</em> for JS(X) files and use <em>ts-loader</em> for TS(X) files, but it didn&#8217;t work &#8211; we were getting weird compilation errors. </p>



<p class="wp-block-paragraph">Then we tried to compile everything using <em>ts-loader</em> and then recompile it again using <em>babel</em> to ensure (as we initially thought would be wise) backwards compatibility. We also couldn&#8217;t make it working.</p>



<p class="wp-block-paragraph"><strong>Finally, we decided to compile everything &#8211; both JavaScript and TypeScript files &#8211; using <em>ts-loader</em></strong> (including React files). It worked, except source code maps. When we tried to debug in Chrome console it seemed the source code is not refreshing properly after rebuilding. Breakpoints were often not hit and the debugging didn&#8217;t seem right. </p>



<p class="wp-block-paragraph">After a bit of struggling we found a solution. We set <a href="https://webpack.js.org/configuration/devtool/" target="_blank" rel="noreferrer noopener">devtool</a> webpack option to <em>eval-source-map</em> and configured <em><a href="https://www.npmjs.com/package/source-map-loader" target="_blank" rel="noreferrer noopener">source-map-loader</a></em> for <em>.js</em> files. Finally, the proper part of webpack config looks as follows:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110022" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-webpack_partial-config-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="webpack_partial.config.js content, created by dsibinski on 09:40AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="webpack_partial.config.js">
        <tr>
          <td id="file-webpack_partial-config-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-webpack_partial-config-js-LC1" class="blob-code blob-code-inner js-file-line">devtool: &quot;eval-source-map&quot;,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-webpack_partial-config-js-LC2" class="blob-code blob-code-inner js-file-line">module: {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-webpack_partial-config-js-LC3" class="blob-code blob-code-inner js-file-line">    rules: [</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-webpack_partial-config-js-LC4" class="blob-code blob-code-inner js-file-line">        { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-webpack_partial-config-js-LC5" class="blob-code blob-code-inner js-file-line">            enforce: &quot;pre&quot;, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-webpack_partial-config-js-LC6" class="blob-code blob-code-inner js-file-line">            test: /\.js$/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-webpack_partial-config-js-LC7" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/, </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-webpack_partial-config-js-LC8" class="blob-code blob-code-inner js-file-line">            loader: &quot;source-map-loader&quot; </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-webpack_partial-config-js-LC9" class="blob-code blob-code-inner js-file-line">        },</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-webpack_partial-config-js-LC10" class="blob-code blob-code-inner js-file-line">        {</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-webpack_partial-config-js-LC11" class="blob-code blob-code-inner js-file-line">            test: /\.(t|j)sx?$/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-webpack_partial-config-js-LC12" class="blob-code blob-code-inner js-file-line">            exclude: /node_modules/,</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-webpack_partial-config-js-LC13" class="blob-code blob-code-inner js-file-line">            use: { </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-webpack_partial-config-js-LC14" class="blob-code blob-code-inner js-file-line">                loader: &#39;ts-loader&#39;</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-webpack_partial-config-js-LC15" class="blob-code blob-code-inner js-file-line">            }</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-webpack_partial-config-js-LC16" class="blob-code blob-code-inner js-file-line">        },  </td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-webpack_partial-config-js-LC17" class="blob-code blob-code-inner js-file-line">    ],</td>
        </tr>
        <tr>
          <td id="file-webpack_partial-config-js-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-webpack_partial-config-js-LC18" class="blob-code blob-code-inner js-file-line">},</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3/raw/6e5f9baf9bf87fec5c43cccf25e5610607c36fa6/webpack_partial.config.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/2cb3c4c10fe63a9020508c20fa31eef3#file-webpack_partial-config-js" class="Link--inTextBlock">
          webpack_partial.config.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>So far we also haven&#8217;t noticed any issues related to backwards compatibility that were theoretically solved by <em>babel</em>. TypeScript compiler does its job very well.</p>



<h3 class="wp-block-heading">Complicated JS -&gt; TS refactoring</h3>



<p class="wp-block-paragraph">I found out that JS to TS refactoring is not always an easy task. <strong>Some things that are allowed by JavaScript are not valid in TypeScript</strong>. In most cases it means that something was wrong with your JavaScript code, but we all know how it is with legacy code refactoring <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="has-dark-gray-color has-text-color wp-block-paragraph">As an example, we had several functions that we added to a <span style="color:#ef7604" class="tadv-color">String</span> prototype in JavaScript:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110060" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-js" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-javascript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.js content, created by dsibinski on 09:47AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.js">
        <tr>
          <td id="file-string_prototype_helpers-js-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-js-LC1" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-js-LC2" class="blob-code blob-code-inner js-file-line">        return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-js-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-js-LC3" class="blob-code blob-code-inner js-file-line">    };</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc/raw/d67095fec29dee3eda04be5994faa58f7f94cee7/string_prototype_helpers.js" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/5e9553424d7441fddefee5f2519ad6dc#file-string_prototype_helpers-js" class="Link--inTextBlock">
          string_prototype_helpers.js
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>Such code becomes invalid in TypeScript:</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="782" height="174" data-attachment-id="3862" data-permalink="https://www.codejourney.net/is-it-worth-migrating-to-typescript/typescript_prototype_functions_error/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" data-orig-size="782,174" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TypeScript_prototype_functions_error" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?fit=782%2C174&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=782%2C174&#038;ssl=1" alt="Migrating to TypeScript: TS error about non-existing function on String prototype in VS Code" class="wp-image-3862" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?w=782&amp;ssl=1 782w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=300%2C67&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=768%2C171&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2020/08/TypeScript_prototype_functions_error.png?resize=676%2C150&amp;ssl=1 676w" sizes="auto, (max-width: 782px) 100vw, 782px" /><figcaption>TypeScript complaining about non-existing function</figcaption></figure>



<p class="wp-block-paragraph">A non-obvious solution to that issue is to extend <span style="color:#ef7604" class="tadv-color">String</span> interface by declaring typed functions you want to add:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist105110103" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-string_prototype_helpers-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="string_prototype_helpers.ts content, created by dsibinski on 09:53AM on August 29, 2020."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="string_prototype_helpers.ts">
        <tr>
          <td id="file-string_prototype_helpers-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-string_prototype_helpers-ts-LC1" class="blob-code blob-code-inner js-file-line">interface String {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-string_prototype_helpers-ts-LC2" class="blob-code blob-code-inner js-file-line">    contains(this : string, it : any): boolean;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-string_prototype_helpers-ts-LC3" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-string_prototype_helpers-ts-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-string_prototype_helpers-ts-LC5" class="blob-code blob-code-inner js-file-line">String.prototype.contains = function (it) {</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-string_prototype_helpers-ts-LC6" class="blob-code blob-code-inner js-file-line">    return this.indexOf(it) != -1;</td>
        </tr>
        <tr>
          <td id="file-string_prototype_helpers-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-string_prototype_helpers-ts-LC7" class="blob-code blob-code-inner js-file-line">};</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f/raw/92dd7b6a53393c445096b7b63ba08149acf256c5/string_prototype_helpers.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/f0cd64ae8967aee9a0cfc13409259e1f#file-string_prototype_helpers-ts" class="Link--inTextBlock">
          string_prototype_helpers.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>There are more subtle difficulties like that you can meet while migrating JS code to TypeScript. However, in the end it gives you a possibility to make your codebase better.</p>



<h3 class="wp-block-heading">Keeping view models in sync</h3>



<p class="wp-block-paragraph">An issue I didn&#8217;t think about before migrating to TypeScript was a need to keep frontend and backend view models in sync.</p>



<p class="wp-block-paragraph">One of the first things you&#8217;d like to have in your TypeScript codebase is to have as much typed data as possible. We use .NET and C# as the backend of our application. ASP.NET MVC controllers returned the strongly-typed objects into the previously chaotic and untyped JS world. Now we are strongly-typed with TypeScript, so we&#8217;d like all this data typed as well <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Here comes the problem. First of all <strong>our C# data models which we returned from the controllers were not the best</strong>. In most cases we returned a DTO object which contained many properties from which only few were used by JavaScript code. We never saw this problem, because in JS we just dynamically typed properties names we wanted to use. We didn&#8217;t see how much of not needed data is sent from ASP controllers to the web browser.</p>



<p class="wp-block-paragraph">Now <strong>with TypeScript we needed to create these objects definitions also in TypeScript</strong>. Having a huge DTO object returned from the controller, with another X objects on which this DTO depends, it was a nightmare. <strong>It turned out that for a single DTO I had to create 10-15 TypeScript objects just to use 5-10 properties in the frontend code!</strong></p>



<p class="wp-block-paragraph">That&#8217;s the moment when we came to the necessity of <strong>creating web view models</strong>. The idea is to <strong>return a view model from a controller, not the whole DTO object. This view model contains only the data which is needed by TypeScript (frontend)</strong>.</p>



<p class="wp-block-paragraph">I think this is nothing new for experienced web developers. However, now comes the question: <strong>how do we keep backend (C#) view models in sync with frontend (TypeScript) ones?</strong></p>



<p class="wp-block-paragraph">Unfortunately, I haven&#8217;t found a perfect solution for that. The best method I came up with is&#8230; <strong>manually keeping these view models in sync</strong>. </p>



<p class="wp-block-paragraph">There&#8217;s a <a href="https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.csharp-to-typescript" target="_blank" rel="noreferrer noopener">C# to TypeScript</a> VS Code extension which allows to paste the copied C# code as its TypeScript equivalent. It makes the job a bit easier. It even has a <a href="https://www.nuget.org/packages/CSharpToTypeScript.CLITool/" target="_blank" rel="noreferrer noopener">CLI tool</a>, but it produces a single <em>.ts</em> file from a single <em>.cs</em> file. If you have multiple objects in a single C# file it will produce a single TypeScript file with all these objects. If any of those objects is used in other files (unfortunately we have many of such cases), these dependencies will not be automatically added as imports in the auto-generated <em>.ts</em> files.</p>



<p class="wp-block-paragraph">However, I don&#8217;t find it very problematic for now. As soon as the TS view models are created, we just need to update them as often as we update C# view models. I think this is a very common issue so if you know any better solution here &#8211; please share in the comments <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Migrating to TypeScript &#8211; summary</h2>



<p class="wp-block-paragraph">Migrating to TypeScript has been a very interesting and rewarding process. Compared to vanilla JavaScript, TypeScript lets programmers see many problems. This allows to see how bad our codebase was. We even realized that our server-side C# code was not the best (see the section about view models above). Thanks to introducing TypeScript we improved a lot of our JavaScript and C# code, including its architecture.</p>



<p class="wp-block-paragraph">I think that TypeScript uses many simple concepts under the hood and it makes a lot of things possible (see <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">keyof</a> or <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types" target="_blank" rel="noreferrer noopener">unknown</a>). In many cases TypeScript <em>lets</em> you do something, but <em>doesn&#8217;t force</em> you to do it. That&#8217;s the beauty of this typed JavaScript world <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/is-it-worth-migrating-to-typescript/">Is It Worth Migrating to TypeScript?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/is-it-worth-migrating-to-typescript/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3840</post-id>	</item>
		<item>
		<title>C# 8: Default Interface Methods Implementation</title>
		<link>https://www.codejourney.net/csharp-8-default-interface-methods/</link>
					<comments>https://www.codejourney.net/csharp-8-default-interface-methods/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 20 Feb 2019 14:00:25 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C#8.0]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3495</guid>

					<description><![CDATA[<p>Continuing to examine new C# 8 features, today we are taking a look at a bit controversial one. It&#8217;s a possibility to provide default interface methods implementation. How will this possibility change the way we write C#? Why is it being introduced? I&#8217;ll try to address these questions today 🙂 Interfaces today As we all&#8230;</p>
<p>The post <a href="https://www.codejourney.net/csharp-8-default-interface-methods/">C# 8: Default Interface Methods Implementation</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Continuing to examine <a rel="noreferrer noopener" aria-label="new C# 8 features (opens in a new tab)" href="https://www.codejourney.net/tag/c8-0/" target="_blank">new C# 8 features</a>, today we are taking a look at a bit controversial one. It&#8217;s a possibility to provide <strong>default interface methods</strong> <strong>implementation</strong>. </p>



<p class="wp-block-paragraph">How will this possibility change the way we write C#? Why is it being introduced? I&#8217;ll try to address these questions today <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3495"></span>



<h2 class="wp-block-heading">Interfaces today</h2>



<p class="wp-block-paragraph">As we all know from the current version of C#, interfaces allow to define a kind of contract, which must be respected by a class implementing it. Today interfaces can only contain definitions of methods (with no body). These methods are then actually implemented by concrete classes. If a class doesn&#8217;t implement all of its interface&#8217;s methods, compiler produces an error.</p>



<p class="wp-block-paragraph">What&#8217;s problematic in this approach? Assuming that you have the following interface and class(es) implementing it:</p>



<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94701778" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-interfaceandclass-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="InterfaceAndClass.cs content, created by dsibinski on 05:42PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="InterfaceAndClass.cs">
        <tr>
          <td id="file-interfaceandclass-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-interfaceandclass-cs-LC1" class="blob-code blob-code-inner js-file-line">  interface IDeveloper</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-interfaceandclass-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-interfaceandclass-cs-LC3" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language, DateTime dueDate);</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-interfaceandclass-cs-LC4" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-interfaceandclass-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-interfaceandclass-cs-LC6" class="blob-code blob-code-inner js-file-line">  class BackendDev : IDeveloper</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-interfaceandclass-cs-LC7" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-interfaceandclass-cs-LC8" class="blob-code blob-code-inner js-file-line">      public void LearnNewLanguage(string language, DateTime dueDate)</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-interfaceandclass-cs-LC9" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-interfaceandclass-cs-LC10" class="blob-code blob-code-inner js-file-line">          // Learning new language&#8230;</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-interfaceandclass-cs-LC11" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-interfaceandclass-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-interfaceandclass-cs-LC12" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/7b5c3454e4976c1b96ac97500be949fc/raw/cb6412facda3f0b612bc289084dcb211536a6e2c/InterfaceAndClass.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/7b5c3454e4976c1b96ac97500be949fc#file-interfaceandclass-cs" class="Link--inTextBlock">
          InterfaceAndClass.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>


<p>With time, you may want to extend <span style="color: #ff6600;">IDeveloper</span> interface by adding a new method, for instance:</p>


<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94701794" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-interfacemodified-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="InterfaceModified.cs content, created by dsibinski on 05:44PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="InterfaceModified.cs">
        <tr>
          <td id="file-interfacemodified-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-interfacemodified-cs-LC1" class="blob-code blob-code-inner js-file-line">  interface IDeveloper</td>
        </tr>
        <tr>
          <td id="file-interfacemodified-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-interfacemodified-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-interfacemodified-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-interfacemodified-cs-LC3" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language, DateTime dueDate);  </td>
        </tr>
        <tr>
          <td id="file-interfacemodified-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-interfacemodified-cs-LC4" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language); // new method added</td>
        </tr>
        <tr>
          <td id="file-interfacemodified-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-interfacemodified-cs-LC5" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/509cee33619a492fe29555d0039230f9/raw/557c447d23512860c9af5b2563b3d17d7256d598/InterfaceModified.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/509cee33619a492fe29555d0039230f9#file-interfacemodified-cs" class="Link--inTextBlock">
          InterfaceModified.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">Now you have a problem, because the <strong>new method must be implemented in all places where the interface was used</strong>. Compiler gives you an error as long as it&#8217;s not done: </p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="900" height="400" data-attachment-id="3508" data-permalink="https://www.codejourney.net/csharp-8-default-interface-methods/interfacemembernotimplemented-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?fit=900%2C400&amp;ssl=1" data-orig-size="900,400" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="InterfaceMemberNotImplemented" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?fit=900%2C400&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?resize=900%2C400&#038;ssl=1" alt="C# 8: Default Interface Methods Implementation: C# compilation error - interface member not implemented" class="wp-image-3508" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?w=900&amp;ssl=1 900w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?resize=300%2C133&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?resize=768%2C341&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/InterfaceMemberNotImplemented-1.png?resize=676%2C300&amp;ssl=1 676w" sizes="auto, (max-width: 900px) 100vw, 900px" /><figcaption>C# compilation error &#8211; interface member not implemented</figcaption></figure>


<p>If your interface is used in many places, also by another teams or developers (which is often the case in reality), <strong>this is a breaking change <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></p>
<p>It may be really painful, depending on how extensively your interface is used. In any case, all classes based on the <span style="color: #ff6600;">IDeveloper</span> interface must implement the new <span style="color: #ff6600;">LearnNewLanguage(string language)</span> method. Only then the code compiles.</p>
<p>One of the reasons for&nbsp;<a href="https://github.com/dotnet/csharplang/issues/52" target="_blank" rel="noopener">introducing into C# default interface methods</a> is to avoid such breaking changes scenarios <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<h2 class="wp-block-heading">Default Interface Methods</h2>



<p class="wp-block-paragraph">As we can read in the <a rel="noreferrer noopener" aria-label="feature's design notes (opens in a new tab)" href="https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md" target="_blank">feature&#8217;s design notes</a>, an inspiration for it is a similar concept already alive in Java &#8211; <em><a rel="noreferrer noopener" aria-label="Default Methods (opens in a new tab)" href="https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html" target="_blank">Default Methods</a></em>.</p>



<p class="wp-block-paragraph">The main idea of this new C# feature is a possibility to <strong>provide a default implementation of an interface&#8217;s method</strong>.</p>



<h3 class="wp-block-heading">Realization in C# 8.0</h3>



<p class="wp-block-paragraph">In our example using C# 8.0 we&#8217;ll be able to implement it as follows:</p>



<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94702032" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-defaultinterfacemethod-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="DefaultInterfaceMethod.cs content, created by dsibinski on 06:08PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="DefaultInterfaceMethod.cs">
        <tr>
          <td id="file-defaultinterfacemethod-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-defaultinterfacemethod-cs-LC1" class="blob-code blob-code-inner js-file-line">  interface IDeveloper</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-defaultinterfacemethod-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-defaultinterfacemethod-cs-LC3" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language, DateTime dueDate);</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-defaultinterfacemethod-cs-LC4" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-defaultinterfacemethod-cs-LC5" class="blob-code blob-code-inner js-file-line">      {   </td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-defaultinterfacemethod-cs-LC6" class="blob-code blob-code-inner js-file-line">          // default implementation</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-defaultinterfacemethod-cs-LC7" class="blob-code blob-code-inner js-file-line">          LearnNewLanguage(language, DateTime.Now.AddMonths(6));</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-defaultinterfacemethod-cs-LC8" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-defaultinterfacemethod-cs-LC9" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1c6e54a566eb9854cd18f7a535fb116b/raw/8285fe2333fd7ba4a713d9953dc19e9c50fc1c71/DefaultInterfaceMethod.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1c6e54a566eb9854cd18f7a535fb116b#file-defaultinterfacemethod-cs" class="Link--inTextBlock">
          DefaultInterfaceMethod.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>


<p>In that case, our class implementing the <span style="color: #ff6600;">IDeveloper</span> interface can legally not implement this new method and there will be no compilation error:</p>


<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94702168" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-defaultinterfacemethod_usage-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="DefaultInterfaceMethod_usage.cs content, created by dsibinski on 06:22PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="DefaultInterfaceMethod_usage.cs">
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC1" class="blob-code blob-code-inner js-file-line">  interface IDeveloper</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC3" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language, DateTime dueDate);</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC4" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC5" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC6" class="blob-code blob-code-inner js-file-line">          // default implementation</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC7" class="blob-code blob-code-inner js-file-line">          LearnNewLanguage(language, DateTime.Now.AddMonths(6));</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC8" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC9" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC10" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC11" class="blob-code blob-code-inner js-file-line">  class BackendDev : IDeveloper // compiles OK</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC12" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC13" class="blob-code blob-code-inner js-file-line">      public void LearnNewLanguage(string language, DateTime dueDate)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC14" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC15" class="blob-code blob-code-inner js-file-line">          // Learning new language&#8230;</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC16" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC17" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC18" class="blob-code blob-code-inner js-file-line">  </td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC19" class="blob-code blob-code-inner js-file-line">  class Program</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC20" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC21" class="blob-code blob-code-inner js-file-line">      static void Main(string[] args)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC22" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC23" class="blob-code blob-code-inner js-file-line">          IDeveloper dev = new BackendDev();</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC24" class="blob-code blob-code-inner js-file-line">          dev.LearnNewLanguage(&quot;Rust&quot;); // OK &#8211; default implementation of</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC25" class="blob-code blob-code-inner js-file-line">                                        // IDeveloper.LearnNewLanguage(string language) is called</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC26" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-defaultinterfacemethod_usage-cs-LC27" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1a1af2c889fe5f101c59e65cf1107b3b/raw/aa6a0e5f0be3e2696d0b978410bf44d1fece564d/DefaultInterfaceMethod_usage.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1a1af2c889fe5f101c59e65cf1107b3b#file-defaultinterfacemethod_usage-cs" class="Link--inTextBlock">
          DefaultInterfaceMethod_usage.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>


<p>Notice that it only works when&nbsp;<span style="color: #ff6600;">BackendDev</span> is contextually treated as <span style="color: #ff6600;">IDeveloper</span>. It means that a class doesn&#8217;t inherit members from the interfaces it implements:</p>


<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94704015" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-defaultinterfacemethod_usage_nok-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="DefaultInterfaceMethod_usage_NOK.cs content, created by dsibinski on 09:19PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="DefaultInterfaceMethod_usage_NOK.cs">
        <tr>
          <td id="file-defaultinterfacemethod_usage_nok-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-defaultinterfacemethod_usage_nok-cs-LC1" class="blob-code blob-code-inner js-file-line">  BackendDev dev = new BackendDev();	          </td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage_nok-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-defaultinterfacemethod_usage_nok-cs-LC2" class="blob-code blob-code-inner js-file-line">  dev.LearnNewLanguage(&quot;Rust&quot;); // compilation error: class &#39;BackendDev&#39; </td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_usage_nok-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-defaultinterfacemethod_usage_nok-cs-LC3" class="blob-code blob-code-inner js-file-line">                                // does not contain a member &#39;LearnNewLanguage&#39;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/4a9a2ccf9163390d9c52b86e7491a055/raw/0572886c2ec17de6a38719a3e96c1d2a373964b4/DefaultInterfaceMethod_usage_NOK.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/4a9a2ccf9163390d9c52b86e7491a055#file-defaultinterfacemethod_usage_nok-cs" class="Link--inTextBlock">
          DefaultInterfaceMethod_usage_NOK.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<h3 class="wp-block-heading">What about multiple inheritance?</h3>



<p class="wp-block-paragraph">As some of you probably realized, this new feature exposes C# to a <a rel="noreferrer noopener" aria-label="multiple inheritance problem (opens in a new tab)" href="https://en.wikipedia.org/wiki/Multiple_inheritance" target="_blank">multiple inheritance problem</a> (also known as <em>Diamond of Death</em>). So far C# didn&#8217;t have this issue, because we can only inherit from a single class. We can implement multiple interfaces, but so far the interfaces couldn&#8217;t provide methods&#8217; implementation. Because of that, there was no <em>Diamond of Death</em> possible. Soon it&#8217;s gonna change <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h4 class="wp-block-heading"><strong>Diamond of Death in C# 8</strong></h4>



<p class="wp-block-paragraph">In case of C# default interface methods we may illustrate this issue with the following code:</p>



<figure class="wp-block-embed aligncenter"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94702504" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-defaultinterfacemethod_diamondofdeath-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="DefaultInterfaceMethod_DiamondOfDeath.cs content, created by dsibinski on 06:53PM on February 17, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="DefaultInterfaceMethod_DiamondOfDeath.cs">
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC1" class="blob-code blob-code-inner js-file-line">  interface IDeveloper</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC2" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC3" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC4" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC5" class="blob-code blob-code-inner js-file-line">          Console.Write($&quot;Learning {language} in a default way.&quot;);</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC6" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC7" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC9" class="blob-code blob-code-inner js-file-line">  interface IBackendDev : IDeveloper</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC10" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC11" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC12" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC13" class="blob-code blob-code-inner js-file-line">          Console.Write($&quot;Learning {language} in a backend way.&quot;);</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC14" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC15" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC17" class="blob-code blob-code-inner js-file-line">  interface IFrontendDev : IDeveloper</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC18" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC19" class="blob-code blob-code-inner js-file-line">      void LearnNewLanguage(string language)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC20" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC21" class="blob-code blob-code-inner js-file-line">          Console.Write($&quot;Learning {language} in a frontend way.&quot;);</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC22" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC23" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC24" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC25" class="blob-code blob-code-inner js-file-line">  interface IFullStackDev : IBackendDev, IFrontendDev { } // uses default implementation, </td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC26" class="blob-code blob-code-inner js-file-line">                                                          // of LearnNewLanguage, but which one?</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC27" class="blob-code blob-code-inner js-file-line">  class Dev : IFullStackDev { }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC28" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC29" class="blob-code blob-code-inner js-file-line">  class Program</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC30" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC31" class="blob-code blob-code-inner js-file-line">      static void Main(string[] args)</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC32" class="blob-code blob-code-inner js-file-line">      {</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC33" class="blob-code blob-code-inner js-file-line">          IFullStackDev dev = new Dev();</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC34" class="blob-code blob-code-inner js-file-line">          dev.LearnNewLanguage(&quot;TypeScript&quot;); // which method is called? The one</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC35" class="blob-code blob-code-inner js-file-line">                                              // from IBackendDev or IFrontendDev?</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC36" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-defaultinterfacemethod_diamondofdeath-cs-LC37" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/883f8f3b867572d9108ebe2048d62ee2/raw/39ad6f21746130f40cf0a48c17111032e0885335/DefaultInterfaceMethod_DiamondOfDeath.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/883f8f3b867572d9108ebe2048d62ee2#file-defaultinterfacemethod_diamondofdeath-cs" class="Link--inTextBlock">
          DefaultInterfaceMethod_DiamondOfDeath.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph"><em>Please note that the syntax or places in which compiler generates errors may still change in the final feature&#8217;s version.</em></p>



<p class="wp-block-paragraph">To better illustrate this Diamond of Death example, take a look at the following diagram:</p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="801" height="332" data-attachment-id="3526" data-permalink="https://www.codejourney.net/csharp-8-default-interface-methods/diamondofdeath-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?fit=801%2C332&amp;ssl=1" data-orig-size="801,332" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="DiamondOfDeath" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?fit=801%2C332&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?resize=801%2C332&#038;ssl=1" alt="C# 8: Default Interface Methods Implementation: Diamond of Death example illustration" class="wp-image-3526" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?w=801&amp;ssl=1 801w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?resize=300%2C124&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?resize=768%2C318&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/DiamondOfDeath-1.jpg?resize=676%2C280&amp;ssl=1 676w" sizes="auto, (max-width: 801px) 100vw, 801px" /><figcaption>Diamond of Death example illustration</figcaption></figure>



<p class="wp-block-paragraph">The question is: <strong>which method should be called in such case?</strong></p>



<h4 class="wp-block-heading"><strong>Solution: most specific override rule</strong></h4>



<p class="wp-block-paragraph">C# 8.0 will solve this issue by introducing <a rel="noreferrer noopener" aria-label="the most specific override rule (opens in a new tab)" href="https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md#the-most-specific-override-rule" target="_blank">the most specific override rule</a>. It means that in our case illustrated above, the <strong>compiler will issue an error and won&#8217;t let us do this</strong>.</p>


<p>To avoid this ambiguity, we&#8217;ll be forced to implement or override <span style="color: #ff6600;">LearnNewLanguage(string language)</span> in <span style="color: #ff6600;">IFullStackDev</span> interface. Only then it will be considered the most specific version of the method in the interfaces hierarchy we have. It will then be used when calling the method on objects contextually treated as instances of <span style="color: #ff6600;">IFullStackDev</span>. We could also implement it directly in the <span style="color: #ff6600;">Dev</span> class and use the class (not interface) type. It would then call the most specific method from the class. This way multiple inheritance issue will be eliminated.</p>


<h2 class="wp-block-heading">Compiler for the rescue</h2>



<p class="wp-block-paragraph">There are a lot of other potential ambiguity scenarios that may take place after introducing into C# default interface methods. You can check all of them with potential solutions <a rel="noreferrer noopener" aria-label="are well-discussed on GitHub (opens in a new tab)" href="https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md" target="_blank">well-discussed on GitHub</a>.</p>



<p class="wp-block-paragraph">The general assumption is that <strong>all code which may lead to issues related to default interface methods implementations is detected by the compiler</strong>. In effect, we should get appropriate errors when compiling the source code. That way, programmer can fix all potential conflicts directly when these arise.</p>



<h2 class="wp-block-heading">What about .NET Framework?</h2>



<p class="wp-block-paragraph">What&#8217;s interesting with default interface methods is that <strong>it requres changes in the runtime</strong>. According to <a rel="noreferrer noopener" aria-label="current assumptions (opens in a new tab)" href="https://www.youtube.com/watch?v=HW_FnmnDlGQ&amp;feature=youtu.be&amp;t=3279" target="_blank">current assumptions</a>, it means that <strong>this feature will not work with .NET Framework</strong>! Only CoreCLR and Mono stack runtimes are going to receive these new updates.</p>



<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">As the motivation for introducing into C# default interface methods the language team members mention possibility to interact with some Android and iOS APIs, which already support such feature. They also claim that C# will get the <em><a rel="noreferrer noopener" aria-label="traits programming language feature (opens in a new tab)" href="https://en.wikipedia.org/wiki/Trait_(computer_programming)" target="_blank">traits</a></em><a rel="noreferrer noopener" aria-label="traits programming language feature (opens in a new tab)" href="https://en.wikipedia.org/wiki/Trait_(computer_programming)" target="_blank"> programming language feature</a> with default interface methods.</p>



<p class="wp-block-paragraph">In my opinion this is the most controversial from all <a rel="noreferrer noopener" aria-label="C# 8.0 new features (opens in a new tab)" href="https://www.codejourney.net/tag/c8-0/" target="_blank">C# 8.0 new features</a>. It completely changes something which was obviousness for the developers for years. Probably we&#8217;ll see less breaking changes issues when the interfaces are extended, but <a rel="noreferrer noopener" aria-label="looking on the list of issues and edge cases it produces (opens in a new tab)" href="https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md" target="_blank">looking on the list of issues and edge cases it produces</a>&#8230; Maybe assuming it already works in a similar way in Java we should just accept it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Another interesting, .NET-specific aspect is that this feature will not work with .NET Framework. It&#8217;s probably the very first moment when the difference in pace between .NET Core and Framework is so explicit.</p>



<p class="wp-block-paragraph">I&#8217;m also very curious about the performance implications of default interface methods. I&#8217;ll for sure be following this issue on GitHub to see how it evolves <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph"><strong><u class="remove-format">What do you think? Is it a good idea to introduce default interface methods into C#?</u></strong></p>
<p>The post <a href="https://www.codejourney.net/csharp-8-default-interface-methods/">C# 8: Default Interface Methods Implementation</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/csharp-8-default-interface-methods/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3495</post-id>	</item>
		<item>
		<title>C# 8: Slicing with Indexes and Ranges</title>
		<link>https://www.codejourney.net/csharp-8-slicing-indexes-ranges/</link>
					<comments>https://www.codejourney.net/csharp-8-slicing-indexes-ranges/#comments</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 13 Feb 2019 14:00:02 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C#8.0]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3454</guid>

					<description><![CDATA[<p>C# 8.0 brings us another nice feature called slicing. In order to make it possible, two new concepts are introduced: Indexes and Ranges. Let&#8217;s see how this tiny feature is supposed to make our life easier 🙂 Goal of slicing The main purpose of introducing slicing into the language is to make working with arrays&#8230;</p>
<p>The post <a href="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/">C# 8: Slicing with Indexes and Ranges</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">C# 8.0 brings us another nice feature called <strong>slicing</strong>. In order to make it possible, two new concepts are introduced: Indexes and Ranges.</p>



<p class="wp-block-paragraph">Let&#8217;s see how this tiny feature is supposed to make our life easier <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-3454"></span>



<h2 class="wp-block-heading">Goal of slicing</h2>



<p class="wp-block-paragraph">The main purpose of introducing slicing into the language is to make  working with arrays and strings easier.</p>



<p class="wp-block-paragraph">Currently, when you want to retrieve a fragment of an array (X elements from the array, located for instance in its middle), you can use LINQ, i.e. combination of <a rel="noreferrer noopener" aria-label="Take (opens in a new tab)" href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.take?view=netframework-4.7.2" target="_blank">Take</a> and <a rel="noreferrer noopener" aria-label="Skip (opens in a new tab)" href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skip?view=netframework-4.7.2" target="_blank">Skip</a> methods. You can also <a rel="noreferrer noopener" aria-label="create some extension method (opens in a new tab)" href="https://www.dotnetperls.com/array-slice" target="_blank">create some extension method</a> to provide kind of slicing.</p>



<p class="wp-block-paragraph">To illustrate the current way, using LINQ to retrieve only 2nd, 3rd and 4th elements of an array looks as follows:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94580774" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-arrayslicewithlinq-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ArraySliceWithLinq.cs content, created by dsibinski on 01:22PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ArraySliceWithLinq.cs">
        <tr>
          <td id="file-arrayslicewithlinq-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-arrayslicewithlinq-cs-LC1" class="blob-code blob-code-inner js-file-line">  var array = new[] { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39; , &#39;H&#39;};</td>
        </tr>
        <tr>
          <td id="file-arrayslicewithlinq-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-arrayslicewithlinq-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-arrayslicewithlinq-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-arrayslicewithlinq-cs-LC3" class="blob-code blob-code-inner js-file-line">  var arraySlice = array.Skip(1).Take(3).ToArray(); // contains &#39;B&#39;, &#39;C&#39; and &#39;D&#39;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/c13e6535c6601b033c5d6285a4908305/raw/916b574f79a9b821194d00f0c2fb999ca81ac3fa/ArraySliceWithLinq.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/c13e6535c6601b033c5d6285a4908305#file-arrayslicewithlinq-cs" class="Link--inTextBlock">
          ArraySliceWithLinq.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">C# community and designers decided it&#8217;s not convenient enough, so are <a rel="noreferrer noopener" aria-label="now adding&nbsp;to&nbsp;C#&nbsp;indexes&nbsp;and&nbsp;ranges&nbsp;(in&nbsp;order to provide slicing) (opens in a new tab)" href="https://github.com/dotnet/csharplang/issues/185" target="_blank">now adding&nbsp;to&nbsp;C#&nbsp;8 indexes&nbsp;and&nbsp;ranges&nbsp;(in&nbsp;order to provide slicing)</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">Index</h2>


<p>C# 8.0 comes along with a new object &#8211; <span style="color: #ff6600;">System.Index</span>. It&#8217;s a structure internally and looks as follows:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1016" height="486" data-attachment-id="3460" data-permalink="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/indexstruct/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?fit=1016%2C486&amp;ssl=1" data-orig-size="1016,486" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IndexStruct" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?fit=1016%2C486&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?resize=1016%2C486&#038;ssl=1" alt="C# 8 indexes and ranges: System.Index structure - .NET Core 3.0.0-preview-27324-5" class="wp-image-3460" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?w=1016&amp;ssl=1 1016w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?resize=300%2C144&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?resize=768%2C367&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexStruct.png?resize=676%2C323&amp;ssl=1 676w" sizes="auto, (max-width: 1016px) 100vw, 1016px" /><figcaption>System.Index <em>s</em>tructure &#8211; .NET Core 3.0.0-preview-27324-5</figcaption></figure>


<p>What&#8217;s interesting here, is that the constructor takes the <span style="color: #ff6600;">value</span> of the <span style="color: #000000;">index </span>and boolean flag <span style="color: #ff6600;">fromEnd</span>. Let&#8217;s see how we can use it in practice:</p>


<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94584228" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-indexescsharp8-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="IndexesCsharp8.cs content, created by dsibinski on 04:11PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="IndexesCsharp8.cs">
        <tr>
          <td id="file-indexescsharp8-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-indexescsharp8-cs-LC1" class="blob-code blob-code-inner js-file-line">  var array = new[] { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39; };</td>
        </tr>
        <tr>
          <td id="file-indexescsharp8-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-indexescsharp8-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-indexescsharp8-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-indexescsharp8-cs-LC3" class="blob-code blob-code-inner js-file-line">  Index idx1 = 2;  // 2nd element from the beginning</td>
        </tr>
        <tr>
          <td id="file-indexescsharp8-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-indexescsharp8-cs-LC4" class="blob-code blob-code-inner js-file-line">  Index idx2 = ^3; // 3rd element from the end (^)</td>
        </tr>
        <tr>
          <td id="file-indexescsharp8-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-indexescsharp8-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-indexescsharp8-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-indexescsharp8-cs-LC6" class="blob-code blob-code-inner js-file-line">  Console.WriteLine($&quot;{array[idx1]}, {array[idx2]}&quot;); // prints &quot;C, F&quot;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/798ba2d501ecdbca5c4fe29e5c4ff5a3/raw/32ecae5f14941b2f4ee01ad5d47cf76a05d06739/IndexesCsharp8.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/798ba2d501ecdbca5c4fe29e5c4ff5a3#file-indexescsharp8-cs" class="Link--inTextBlock">
          IndexesCsharp8.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p class="wp-block-paragraph">While the first printed value is nothing special, as you can see we can now use the <strong>hat operator</strong> (^) in order to <strong>index from the end</strong>. The following also works:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94584292" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-indexes_ccharp8_2-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="Indexes_CCharp8_2.cs content, created by dsibinski on 04:14PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="Indexes_CCharp8_2.cs">
        <tr>
          <td id="file-indexes_ccharp8_2-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-indexes_ccharp8_2-cs-LC1" class="blob-code blob-code-inner js-file-line">  var array = new[] { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39; };</td>
        </tr>
        <tr>
          <td id="file-indexes_ccharp8_2-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-indexes_ccharp8_2-cs-LC2" class="blob-code blob-code-inner js-file-line">  Console.WriteLine($&quot;{array[^3]}&quot;); // prints &quot;F&quot; (3rd element from the end)</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/1065a08b53aa7b0e5eb9ca19a3285f19/raw/3af3373353f98f3e0e9ae9d47db0168af5251dcf/Indexes_CCharp8_2.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/1065a08b53aa7b0e5eb9ca19a3285f19#file-indexes_ccharp8_2-cs" class="Link--inTextBlock">
          Indexes_CCharp8_2.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>


<p>It means that the ^ operator is a syntactic sugar for<span style="color: #ff6600;"> Index</span>. I allowed myself to check the IL produced:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="824" height="376" data-attachment-id="3461" data-permalink="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/indexctorsyntacticsugerhat/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?fit=824%2C376&amp;ssl=1" data-orig-size="824,376" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IndexCtorSyntacticSugerHat" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?fit=824%2C376&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?resize=824%2C376&#038;ssl=1" alt="C# 8 indexes and ranges: IL Code behind ^ (hat operator)" class="wp-image-3461" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?w=824&amp;ssl=1 824w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?resize=300%2C137&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?resize=768%2C350&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/IndexCtorSyntacticSugerHat.png?resize=676%2C308&amp;ssl=1 676w" sizes="auto, (max-width: 824px) 100vw, 824px" /><figcaption>IL Code behind ^ (hat operator)</figcaption></figure>


<p>As we suspected &#8211; an instance of <span style="color: #ff6600;">Index</span> is created, passing <strong>3</strong> as <span style="color: #ff6600;">value</span> and <strong>true</strong> as <span style="color: #ff6600;">fromEnd</span>&nbsp;(see the constructor parameters above).</p>


<h2 class="wp-block-heading">Range</h2>


<p>Another concept which uses Indexes is a new structural data type &#8211; <span style="color: #ff6600;">System.Range</span>:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1012" height="478" data-attachment-id="3463" data-permalink="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/rangeusingindexes/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?fit=1012%2C478&amp;ssl=1" data-orig-size="1012,478" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RangeUsingIndexes" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?fit=1012%2C478&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?resize=1012%2C478&#038;ssl=1" alt="C# 8 indexes and ranges: System.Range structure - .NET Core 3.0.0-preview-27324-5" class="wp-image-3463" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?w=1012&amp;ssl=1 1012w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?resize=300%2C142&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?resize=768%2C363&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeUsingIndexes.png?resize=676%2C319&amp;ssl=1 676w" sizes="auto, (max-width: 1012px) 100vw, 1012px" /><figcaption> <em>System.Range structure &#8211; .NET Core 3.0.0-preview-27324-5</em> </figcaption></figure>



<p class="wp-block-paragraph">As you can see, it <strong>really uses Indexes</strong>. We can even try creating it on our own:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94584738" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-rangecsharp8-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RangeCSharp8.cs content, created by dsibinski on 04:35PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RangeCSharp8.cs">
        <tr>
          <td id="file-rangecsharp8-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-rangecsharp8-cs-LC1" class="blob-code blob-code-inner js-file-line">  var array = new[] { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39; };</td>
        </tr>
        <tr>
          <td id="file-rangecsharp8-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-rangecsharp8-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-rangecsharp8-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-rangecsharp8-cs-LC3" class="blob-code blob-code-inner js-file-line">  Range r = Range.Create(2, ^1); // range from 2nd to </td>
        </tr>
        <tr>
          <td id="file-rangecsharp8-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-rangecsharp8-cs-LC4" class="blob-code blob-code-inner js-file-line">                                 // 1st element from the end</td>
        </tr>
        <tr>
          <td id="file-rangecsharp8-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-rangecsharp8-cs-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-rangecsharp8-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-rangecsharp8-cs-LC6" class="blob-code blob-code-inner js-file-line">  Console.WriteLine(array[r]); // prints &quot;CDEFG&quot;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/6621a3ca282c539274851b4bba11c8cf/raw/57acffc675f86be754fef1a451198fa2480ab2a4/RangeCSharp8.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/6621a3ca282c539274851b4bba11c8cf#file-rangecsharp8-cs" class="Link--inTextBlock">
          RangeCSharp8.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>


<p>This doesn&#8217;t really make extracting data from the arrays better than <em>Skip-Take</em> LINQ, does it?</p>
<p>Fortunately, there&#8217;s another friendly C# language element introduced called <em>range expression</em>. It can be written as <span style="color: #ff6600;">x..y</span> and used directly for indexing:</p>
<p><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94584820" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-rangeexpression-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="RangeExpression.cs content, created by dsibinski on 04:39PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="RangeExpression.cs">
        <tr>
          <td id="file-rangeexpression-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-rangeexpression-cs-LC1" class="blob-code blob-code-inner js-file-line">  var array = new[] { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39; };</td>
        </tr>
        <tr>
          <td id="file-rangeexpression-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-rangeexpression-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-rangeexpression-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-rangeexpression-cs-LC3" class="blob-code blob-code-inner js-file-line">  Console.WriteLine(array[2..^1]); // prints &quot;CDEFG&quot;</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/28e64583ab06c323d1154548b48a271e/raw/fb2cd5b0d63f54247e3bc0d8322c7aa88d81eb21/RangeExpression.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/28e64583ab06c323d1154548b48a271e#file-rangeexpression-cs" class="Link--inTextBlock">
          RangeExpression.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</p>
<p>This looks much better! Let&#8217;s see how C# compiler translated our 2 lines of code by looking at the pseudo-C# IL produced:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="504" height="640" data-attachment-id="3464" data-permalink="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/rangearrayilcsharp/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeArrayILCSharp.png?fit=504%2C640&amp;ssl=1" data-orig-size="504,640" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RangeArrayILCSharp" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeArrayILCSharp.png?fit=504%2C640&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeArrayILCSharp.png?resize=504%2C640&#038;ssl=1" alt="C# 8 indexes and ranges: IL (C# pseudo-code) produced when using range expression" class="wp-image-3464" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeArrayILCSharp.png?w=504&amp;ssl=1 504w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/RangeArrayILCSharp.png?resize=236%2C300&amp;ssl=1 236w" sizes="auto, (max-width: 504px) 100vw, 504px" /><figcaption>IL (C# pseudo-code) produced when using range expression</figcaption></figure>



<p class="wp-block-paragraph">Even though we could achieve the same with much less LINQ, C# compiler does a lot of stuff for us, keeping our code simpler to grasp.</p>



<h4 class="wp-block-heading"><strong>Ranges in strings</strong></h4>


<p>All these operations apply also to <span style="color: #ff6600;">strings</span>:</p>
<p><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94585049" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-csharp8_rangestring-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="CSharp8_RangeString.cs content, created by dsibinski on 04:49PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="CSharp8_RangeString.cs">
        <tr>
          <td id="file-csharp8_rangestring-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-csharp8_rangestring-cs-LC1" class="blob-code blob-code-inner js-file-line">  var story = &quot;C# 8 is going to be great!&quot;;</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangestring-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-csharp8_rangestring-cs-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangestring-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-csharp8_rangestring-cs-LC3" class="blob-code blob-code-inner js-file-line">  Console.WriteLine(story[^6..^0]); // prints &quot;great!&quot; (last 6 chars)</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/6f011df284ea03178178cceed6f902b4/raw/1c33e97219a57324005049b9f182916934932784/CSharp8_RangeString.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/6f011df284ea03178178cceed6f902b4#file-csharp8_rangestring-cs" class="Link--inTextBlock">
          CSharp8_RangeString.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</p>
<p></p>


<h4 class="wp-block-heading"><strong>Ranges in foreach loop</strong></h4>


<p>Next interesting usage is in the <span style="color: #ff6600;">foreach</span> loop:</p>
<p><style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist94585228" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-csharp8_rangeforeach-cs" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-c  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="CSharp8_RangeForeach.cs content, created by dsibinski on 05:00PM on February 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="CSharp8_RangeForeach.cs">
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-csharp8_rangeforeach-cs-LC1" class="blob-code blob-code-inner js-file-line">  var devs = new Developer[]</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-csharp8_rangeforeach-cs-LC2" class="blob-code blob-code-inner js-file-line">        {</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-csharp8_rangeforeach-cs-LC3" class="blob-code blob-code-inner js-file-line">            new Developer(&quot;Dawid&quot;),</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-csharp8_rangeforeach-cs-LC4" class="blob-code blob-code-inner js-file-line">            new Developer(&quot;Mark&quot;),</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-csharp8_rangeforeach-cs-LC5" class="blob-code blob-code-inner js-file-line">            new Developer(&quot;John&quot;),</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-csharp8_rangeforeach-cs-LC6" class="blob-code blob-code-inner js-file-line">            new Developer(&quot;Alice&quot;),</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-csharp8_rangeforeach-cs-LC7" class="blob-code blob-code-inner js-file-line">            new Developer(&quot;Kate&quot;)</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-csharp8_rangeforeach-cs-LC8" class="blob-code blob-code-inner js-file-line">        };</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-csharp8_rangeforeach-cs-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-csharp8_rangeforeach-cs-LC10" class="blob-code blob-code-inner js-file-line">  foreach (var dev in devs[1..^2]) // prints &quot;MarkJohn&quot;</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-csharp8_rangeforeach-cs-LC11" class="blob-code blob-code-inner js-file-line">  {</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-csharp8_rangeforeach-cs-LC12" class="blob-code blob-code-inner js-file-line">      Console.Write(dev.FirstName);</td>
        </tr>
        <tr>
          <td id="file-csharp8_rangeforeach-cs-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-csharp8_rangeforeach-cs-LC13" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/92b499a8c0567c88001f7338d149c519/raw/529e6f6428932ace2f5a2932beca25f33947f88b/CSharp8_RangeForeach.cs" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/92b499a8c0567c88001f7338d149c519#file-csharp8_rangeforeach-cs" class="Link--inTextBlock">
          CSharp8_RangeForeach.cs
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</p>


<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">I see these &#8220;little&#8221; C# 8 indexes and ranges as another helpful feature. It&#8217;s less breaking and controversial than <a rel="noreferrer noopener" aria-label="nullable reference types (opens in a new tab)" href="https://www.codejourney.net/2019/02/csharp-8-nullable-reference-types/" target="_blank">nullable reference types</a>, still making us write less C# code in the future.</p>



<p class="wp-block-paragraph">If you&#8217;d like to dig the feature even more, I encourage you to read the <a rel="noreferrer noopener" aria-label="discussions about it on GItHub, (opens in a new tab)" href="https://github.com/dotnet/csharplang/issues/198" target="_blank">discussions about it on GitHub,</a> which I always find very interesting <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Developers, what do you think about C# 8 indexes and ranges? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/csharp-8-slicing-indexes-ranges/">C# 8: Slicing with Indexes and Ranges</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/csharp-8-slicing-indexes-ranges/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3454</post-id>	</item>
		<item>
		<title>C# 8: Nullable Reference Types</title>
		<link>https://www.codejourney.net/csharp-8-nullable-reference-types/</link>
					<comments>https://www.codejourney.net/csharp-8-nullable-reference-types/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 05 Feb 2019 14:00:14 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C#8.0]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=3406</guid>

					<description><![CDATA[<p>In the few next posts I&#8217;d like to share with you some of the most interesting C# 8.0 features. Today we&#8217;re going to start with examining nullable reference types. Let&#8217;s see then 🙂 Learn about building C# 8.0 C# 8.0 is going to be the next major release of C# language. It should be released&#8230;</p>
<p>The post <a href="https://www.codejourney.net/csharp-8-nullable-reference-types/">C# 8: Nullable Reference Types</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In the few next posts I&#8217;d like to share with you some of the most interesting C# 8.0 features. Today we&#8217;re going to start with examining nullable reference types. Let&#8217;s see then <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<span id="more-3406"></span>



<h2 class="wp-block-heading">Learn about building C# 8.0</h2>


<p>C# 8.0 is going to be the next major release of C# language. It should be released by the same time as .NET Core 3.0.</p>
<p>What I find very interesting is <a href="https://github.com/dotnet/csharplang" target="_blank" rel="noopener">C# language GitHub repository</a>. Among others, you can find there very interesting <a href="https://github.com/dotnet/csharplang/tree/master/meetings" target="_blank" rel="noopener">notes from C# language design meetings</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> If you filter well, you can also list so called &#8220;proposals&#8221;, which are current candidates for new C#&#8217;s version (or sub-versions) features. By clicking <a href="https://github.com/dotnet/csharplang/issues?q=is%3Aissue+milestone%3A%228.0+candidate%22+is%3Aopen" target="_blank" rel="noopener">here</a> you can list C# 8.0 candidates.</p>
<p>I will publish a separate post regarding each feature which I find particularly interesting <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>


<h2 class="wp-block-heading">Nullable reference types</h2>



<p class="wp-block-paragraph">First of the C# 8.0 features I&#8217;d like to discuss are <a rel="noreferrer noopener" aria-label="nullable reference types (opens in a new tab)" href="https://github.com/dotnet/csharplang/issues/36" target="_blank">nullable reference types</a>. It seems it&#8217;s going to change the way we write our code, so it&#8217;s worth knowing this feature.</p>



<h3 class="wp-block-heading">A bit of history &#8211; NullReferenceException</h3>


<p>Consider the following code:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="586" height="679" data-attachment-id="3422" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/nullrefcode/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullRefCode.png?fit=586%2C679&amp;ssl=1" data-orig-size="586,679" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NullRefCode" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullRefCode.png?fit=586%2C679&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullRefCode.png?resize=586%2C679&#038;ssl=1" alt="" class="wp-image-3422" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullRefCode.png?w=586&amp;ssl=1 586w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullRefCode.png?resize=259%2C300&amp;ssl=1 259w" sizes="auto, (max-width: 586px) 100vw, 586px" /><figcaption>Gist: <a href="https://gist.github.com/dsibinski/c1c9fabb9f05c1e1fed6a58278dce7e5" target="_blank" rel="noreferrer noopener" aria-label="NullCode.cs (opens in a new tab)">NullCode.cs</a></figcaption></figure>


<p>Guess what happens after executing this as a console app? Of course, our favorite <span style="color: #ff6600;">NullReferenceException</span> is thrown:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="199" data-attachment-id="3423" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/nullreferenceexception-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?fit=1109%2C216&amp;ssl=1" data-orig-size="1109,216" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NullReferenceException" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?fit=1024%2C199&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?resize=1024%2C199&#038;ssl=1" alt="" class="wp-image-3423" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?resize=1024%2C199&amp;ssl=1 1024w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?resize=300%2C58&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?resize=768%2C150&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?resize=676%2C132&amp;ssl=1 676w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullReferenceException-1.png?w=1109&amp;ssl=1 1109w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>


<p>In this case, <span style="color: #ff6600;">jsDev.LastName</span> is of course set to <span style="color: #ff6600;">null</span>.</p>
<p><span style="color: #ff6600;">NullReferenceException</span> has been a nightmare for thousands of developers (and users) for many years. What if, in the cases like our example, we knew before that in this place our object might be <span style="color: #ff6600;">null</span>?</p>


<h3 class="wp-block-heading">New world &#8211; #nullable enable</h3>


<p>For that purpose, C# development team is introducing <strong>nullable reference types</strong>. In essence, it<strong> makes reference types (like <span style="color: #ff6600;">string</span>) non-nullable</strong>! However to not be a tough nut to crack, all issues related to assigning <span style="color: #ff6600;">null</span> value to non-nullable reference types are presented as warnings, not errors.</p>


<p class="wp-block-paragraph">In order to use this feature, you need to enable it.  You can do it with a preprocessor directive <em>#nullable enabled.</em> We can do it directly in the source code file. In the future, it <a rel="noreferrer noopener" aria-label="should also be possible (opens in a new tab)" href="https://github.com/dotnet/project-system/issues/4058" target="_blank">should also be possible</a> to enable it on project level.</p>



<p class="wp-block-paragraph">Notice what happens when we enable it in our example:</p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="616" height="405" data-attachment-id="3425" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/propertynotinitializedwarning/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarning.png?fit=616%2C405&amp;ssl=1" data-orig-size="616,405" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="PropertyNotInitializedWarning" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarning.png?fit=616%2C405&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarning.png?resize=616%2C405&#038;ssl=1" alt="" class="wp-image-3425" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarning.png?w=616&amp;ssl=1 616w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarning.png?resize=300%2C197&amp;ssl=1 300w" sizes="auto, (max-width: 616px) 100vw, 616px" /></figure>


<p>We&#8217;re still able to compile, but this nice warning is displayed <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> As soon as we initialize <span style="color: #ff6600;">LastName</span> property in the constructor, the warning disappears:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="656" height="405" data-attachment-id="3426" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/propertynotinitializedwarningdisappeared/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarningDisappeared.png?fit=656%2C405&amp;ssl=1" data-orig-size="656,405" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="PropertyNotInitializedWarningDisappeared" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarningDisappeared.png?fit=656%2C405&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarningDisappeared.png?resize=656%2C405&#038;ssl=1" alt="" class="wp-image-3426" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarningDisappeared.png?w=656&amp;ssl=1 656w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PropertyNotInitializedWarningDisappeared.png?resize=300%2C185&amp;ssl=1 300w" sizes="auto, (max-width: 656px) 100vw, 656px" /></figure>



<p class="wp-block-paragraph">If you try to cheat, it still works like a charm <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> :</p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="870" height="418" data-attachment-id="3427" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/nullassignationnonnullablestring/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?fit=870%2C418&amp;ssl=1" data-orig-size="870,418" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NullAssignationNonnullableString" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?fit=870%2C418&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?resize=870%2C418&#038;ssl=1" alt="" class="wp-image-3427" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?w=870&amp;ssl=1 870w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?resize=300%2C144&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?resize=768%2C369&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullAssignationNonnullableString.png?resize=676%2C325&amp;ssl=1 676w" sizes="auto, (max-width: 870px) 100vw, 870px" /></figure>


<p>But hey&#8230; what if you actually want <span style="color: #ff6600;">null</span> in this particular <span style="color: #ff6600;">string</span>? <strong>You need to explicitly mark your reference type variable as nullable</strong>. You probably recall nullable value types like <span style="color: #ff6600;">int?</span>, don&#8217;t you (read <a href="https://www.codejourney.net/2018/08/net-internals-02-stack-and-heap-net-data-structures/" target="_blank" rel="noopener">this post</a> if you don&#8217;t remember the difference between value and reference types)? Now you can do the same with non-nullable reference types:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="491" height="342" data-attachment-id="3428" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/nullablereferencestring/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableReferenceString.png?fit=491%2C342&amp;ssl=1" data-orig-size="491,342" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NullableReferenceString" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableReferenceString.png?fit=491%2C342&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableReferenceString.png?resize=491%2C342&#038;ssl=1" alt="" class="wp-image-3428" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableReferenceString.png?w=491&amp;ssl=1 491w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableReferenceString.png?resize=300%2C209&amp;ssl=1 300w" sizes="auto, (max-width: 491px) 100vw, 491px" /></figure>



<p class="wp-block-paragraph">Nonetheless, in such case, the compiler still takes care of us:</p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="774" height="210" data-attachment-id="3429" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/possiblenullwarning/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?fit=774%2C210&amp;ssl=1" data-orig-size="774,210" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="PossibleNullWarning" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?fit=774%2C210&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?resize=774%2C210&#038;ssl=1" alt="" class="wp-image-3429" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?w=774&amp;ssl=1 774w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?resize=300%2C81&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?resize=768%2C208&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/PossibleNullWarning.png?resize=676%2C183&amp;ssl=1 676w" sizes="auto, (max-width: 774px) 100vw, 774px" /></figure>


<p>The final fix is quite obvious &#8211; we need to check for <span style="color: #ff6600;">null</span> first:</p>


<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="691" height="195" data-attachment-id="3430" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/checkingfornull/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?fit=691%2C195&amp;ssl=1" data-orig-size="691,195" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="CheckingForNull" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?fit=691%2C195&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?resize=691%2C195&#038;ssl=1" alt="" class="wp-image-3430" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?w=691&amp;ssl=1 691w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?resize=300%2C85&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/CheckingForNull.png?resize=676%2C191&amp;ssl=1 676w" sizes="auto, (max-width: 691px) 100vw, 691px" /></figure>



<p class="wp-block-paragraph">At this stage all warnings finally disappear. You can find the finished source code <a rel="noreferrer noopener" aria-label="here (opens in a new tab)" href="https://gist.github.com/dsibinski/67c6d315463186bbfa4281dbb6611a25" target="_blank">here</a>.</p>



<h3 class="wp-block-heading">Nullable reference types in IL</h3>



<p class="wp-block-paragraph">The only thing I found in the IL code compiled from source code with <em>#nullable enabled</em> directive was NullableAttribute applied to properties:</p>



<figure class="wp-block-image"><img data-recalc-dims="1" loading="lazy" decoding="async" width="878" height="328" data-attachment-id="3440" data-permalink="https://www.codejourney.net/csharp-8-nullable-reference-types/nullablereftypesil/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?fit=878%2C328&amp;ssl=1" data-orig-size="878,328" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="NullableRefTypesIL" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?fit=878%2C328&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?resize=878%2C328&#038;ssl=1" alt="" class="wp-image-3440" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?w=878&amp;ssl=1 878w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?resize=300%2C112&amp;ssl=1 300w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?resize=768%2C287&amp;ssl=1 768w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2019/02/NullableRefTypesIL.png?resize=676%2C253&amp;ssl=1 676w" sizes="auto, (max-width: 878px) 100vw, 878px" /></figure>



<p class="wp-block-paragraph">It seems that nullable reference types are implemented by applying this attribute to variables, which is only used by the compiler (runtime is not affected).</p>



<h2 class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">I&#8217;m really excited about nullable reference types in C# 8. I personally feel that it even introduces some clarity in the language &#8211; we&#8217;ll have explicit declarations for nullable value and reference types. However, in more complex scenarios it may bring some confusion in regards to reference types and using &#8220;?&#8221; character (like generics or collections &#8211; see <a href="https://codeblog.jonskeet.uk/2018/04/21/first-steps-with-nullable-reference-types/" target="_blank" rel="noreferrer noopener" aria-label="Jon Skeet's post (opens in a new tab)">Jon Skeet&#8217;s post</a> for more details). For sure it&#8217;s a significant step towards eliminating issues with exceptions caused by null references.</p>



<p class="wp-block-paragraph">What do you think about nullable reference types? Is it a good direction in which C# language is going? Share your thoughts in the comments! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.codejourney.net/csharp-8-nullable-reference-types/">C# 8: Nullable Reference Types</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/csharp-8-nullable-reference-types/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3406</post-id>	</item>
		<item>
		<title>10 Most Shocking JavaScript Features for C# Developers</title>
		<link>https://www.codejourney.net/10-most-shocking-javascript-features-for-csharp-developers/</link>
					<comments>https://www.codejourney.net/10-most-shocking-javascript-features-for-csharp-developers/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Wed, 07 Nov 2018 14:00:43 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=2999</guid>

					<description><![CDATA[