<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sean</title>
    <description>The latest articles on DEV Community by Sean (@seantwie03).</description>
    <link>https://dev.to/seantwie03</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F113845%2F8edaeb59-93df-4e92-a5d0-a325a6215d03.jpeg</url>
      <title>DEV Community: Sean</title>
      <link>https://dev.to/seantwie03</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seantwie03"/>
    <language>en</language>
    <item>
      <title>Learn Clojure Interactively Using eBooks</title>
      <dc:creator>Sean</dc:creator>
      <pubDate>Wed, 21 Oct 2020 10:42:52 +0000</pubDate>
      <link>https://dev.to/seantwie03/learn-clojure-interactively-using-ebooks-14ed</link>
      <guid>https://dev.to/seantwie03/learn-clojure-interactively-using-ebooks-14ed</guid>
      <description>&lt;p&gt;I recently decided to learn a bit of Clojure.  My first step was to setup my &lt;a href="https://neovim.io/"&gt;preferred editor&lt;/a&gt; with a &lt;a href="https://github.com/Olical/conjure"&gt;Clojure plugin&lt;/a&gt;.  The Clojure tooling allows a developer to write code in a text buffer, then use a keyboard shortcut to execute a section of that code in the REPL.  This instant feedback makes for a really great developer experience.&lt;/p&gt;

&lt;p&gt;After toying around a bit, I bought a copy of &lt;a href="https://pragprog.com/titles/roclojure/getting-clojure/"&gt;Getting Clojure&lt;/a&gt; by Russ Olsen from the Pragmatic Bookshelf.  One of their download options is PDF format.  I read through the first chapter, typing the code examples into a text buffer and using a keyboard shortcut to execute them in the REPL.  Typing these examples got a bit tedious, so I started copying and pasting.  That's when I got an idea.&lt;/p&gt;

&lt;p&gt;If only I could open this book in my editor, then I could just execute the snippets without having to type them.&lt;/p&gt;

&lt;p&gt;So, I converted the PDF to a .clj text file using &lt;a href="http://manpages.ubuntu.com/manpages/bionic/man1/pdftotext.1.html"&gt;pdftotext&lt;/a&gt; (I used the -layout flag for better formatting).  Then, I opened the newly converted text file in my editor and was able to execute the code-snippets with a keyboard shortcut.  Since this is just a plain-text file, I am able to modify the existing code and try things out with instant feedback.  This is a really interactive and engaging way to learn Clojure.&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>learning</category>
    </item>
    <item>
      <title>Generics in C# (Part 3 - Generic Classes)</title>
      <dc:creator>Sean</dc:creator>
      <pubDate>Sun, 07 Apr 2019 13:29:50 +0000</pubDate>
      <link>https://dev.to/seantwie03/generics-in-c-part-3-generic-classes-1e96</link>
      <guid>https://dev.to/seantwie03/generics-in-c-part-3-generic-classes-1e96</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This is the third part of my series on C# Generics (&lt;a href="https://dev.to/seantwie03/generics-in-c-part-1-generics-in-collections-2dm1"&gt;Part One&lt;/a&gt;, &lt;a href="https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho"&gt;Part Two&lt;/a&gt;).  In this article I will explain how to create Generic classes.  To demonstrate this I will create a static class prints all items in a List using the InvariantCulture format.&lt;/p&gt;

&lt;p&gt;One place where cultures differ is on DateTime.  DotNet has an interface called IFormattable that implements a ToString() method that accepts a formatProvider.  Using this interface and a &lt;strong&gt;Type constraint&lt;/strong&gt; I will demonstrate how to print out IFormattables using Invariant culture in the static class InvariantCulturePrinter.&lt;/p&gt;

&lt;h2&gt;
  
  
  InvariantCulturePrinter
&lt;/h2&gt;

&lt;p&gt;First, let's look at the static class InvariantCulturePrinter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3l5sD-kA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/z5vqqaot4z62mpaf6kqg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3l5sD-kA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/z5vqqaot4z62mpaf6kqg.jpg" alt="InvariantCulturePrinter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a Generic class which works in much the same way as the generic method in &lt;a href="https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho"&gt;Part Two&lt;/a&gt;.  The T's are replaced by the argument that is passed into the Type parameter.  The main difference is the "where T : IFormattable".  This is a Type constraint.&lt;/p&gt;

&lt;p&gt;The PrintList() method uses a ToString() method that has two parameters.  The first parameter is the stringFormat and the second parameter is the formatProvider.  If this is a generic method that accepts any generic List as an argument, how can we be sure the argument will contain a type that supports this ToString(stringFormat, formatProvider) implementation?&lt;/p&gt;

&lt;p&gt;That is where the type constraint comes in.  IFormattable specifies the ToString(stringFormat, formatProvider) method.  So specifying IFormattable as the Type constrain will ensure this ToString implementation is always available.&lt;/p&gt;

</description>
      <category>generics</category>
    </item>
    <item>
      <title>Generics in C# (Part 2 - Creating Generic Methods)</title>
      <dc:creator>Sean</dc:creator>
      <pubDate>Sun, 07 Apr 2019 13:21:14 +0000</pubDate>
      <link>https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho</link>
      <guid>https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/seantwie03/generics-in-c-part-1-generics-in-collections-2dm1"&gt;Part One&lt;/a&gt; of this series is a general overview of Generics that explored why they are used in Lists.  This article will explain how to create your own Generic methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concatenate Arrays of Any Type
&lt;/h2&gt;

&lt;p&gt;I will demonstrate Generic methods by creating an &lt;a href="https://www.tutorialsteacher.com/csharp/csharp-extension-method"&gt;extension method&lt;/a&gt; for System.Array.  This extension method will combine two arrays, and since it is Generic it will work on any type of array; int[], string[], etc.&lt;/p&gt;

&lt;p&gt;First let's look at how the method is called from Main().&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V4Vt8K0m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0y1jou6bfssev2poz68u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V4Vt8K0m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0y1jou6bfssev2poz68u.jpg" alt="Main"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since this is an extension method on System.Array, I create two arrays, then call Concatenate on the first array; passing the second array as an argument.  I then repeat the same steps using a string array to prove the method will work on multiple types.  In the second section I did not explicitly specify the Type parameter &amp;lt;string&amp;gt;, but the compiler can work it out, since the result is being assigned to a string[].&lt;/p&gt;

&lt;p&gt;Now let's look at the Concatenate extension method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sy1YR3WE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ru3sr7ockfbxyvekkl46.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sy1YR3WE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ru3sr7ockfbxyvekkl46.jpg" alt="ArrayExtension"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, I would like to point out the &lt;strong&gt;Type parameter&lt;/strong&gt; after the method name. &amp;lt;T&amp;gt; signifies this is a generic method.  You'll notice the return type and method parameters are also T.  All these T's are replaced with whatever argument is passed into the Type parameter.&lt;/p&gt;

&lt;p&gt;In the first code block in Main() I explicitly specify the type parameter, passing in &amp;lt;int&amp;gt;, so the compiler knows to replace all occurrences of T with int.  In the second section of Main() I am assigning the result of Concatenate to a string[] so the compiler knows to replace all occurrences of T with string.&lt;/p&gt;

&lt;p&gt;Continue to &lt;a href="https://dev.to/seantwie03/generics-in-c-part-3-generic-classes-1e96"&gt;Part Three&lt;/a&gt;, where I will cover how to create Generic classes.&lt;/p&gt;

</description>
      <category>generics</category>
    </item>
    <item>
      <title>Generics in C# (Part 1 - Generics in Collections)</title>
      <dc:creator>Sean</dc:creator>
      <pubDate>Sun, 07 Apr 2019 13:17:12 +0000</pubDate>
      <link>https://dev.to/seantwie03/generics-in-c-part-1-generics-in-collections-2dm1</link>
      <guid>https://dev.to/seantwie03/generics-in-c-part-1-generics-in-collections-2dm1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Generic types were introduced to C# 2 in 2005.  Since 2005, Generics have become a pivotal part of C#, empowering things like Lists and Async/Await.  If you started learning or using C# after version 2, you may be using Generics on a daily basis without really knowing what they are.  This series (&lt;a href="https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho"&gt;Part Two&lt;/a&gt;, &lt;a href="https://dev.to/seantwie03/generics-in-c-part-3-generic-classes-1e96"&gt;Part Three&lt;/a&gt;) will try to bring some clarity to Generics in C#.&lt;/p&gt;

&lt;p&gt;One common use of Generics is in List&amp;lt;T&amp;gt;. Where &amp;lt;T&amp;gt; specifies a &lt;strong&gt;Type Parameter&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1e9hogg1esczsbsj41lr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1e9hogg1esczsbsj41lr.jpg" alt="ListOfT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Before Generics - C# 1
&lt;/h2&gt;

&lt;p&gt;Before diving into Generics, it would be helpful to think about what kind of problem they solve.  The best way to do this is to look back at C# 1.  Before Generics, C# had Arrays and ArrayLists.  &lt;/p&gt;

&lt;p&gt;To declare an array, you must specify the type of the array and the number of elements it will contain.  Declaring the type is very beneficial, having strong types is one of the benefits of C#, but declaring the size up front can be problematic.  This can lead to a lot of repetitive code to manage the size of the array as you create new bigger arrays and copy the old values into it, and don't forget at the end of your method to shrink the array down to the final size.&lt;/p&gt;

&lt;p&gt;ArrayLists are resizable, so they solve that problem, but they accept anything of type Object.  Which means to work with the values inside of an ArrayList requires casting or boxing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffc1fh3vfw6ng8fh9wa6p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffc1fh3vfw6ng8fh9wa6p.jpg" alt="ArrayListOfEveryType"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Generics Solve the List Problem
&lt;/h2&gt;

&lt;p&gt;Lists in the System.Collections.Generic namespace give us the best of both worlds.  Lists are strongly typed and resizable.  To declare a List, an argument must be passed into the Type parameter (Type parameters are surrounded by &amp;lt; &amp;gt; symbols).  This argument determines the type of the List.  Once declared, only objects of that type are allowed to be added to the List.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkff4ih0dhs14xrm60kyv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkff4ih0dhs14xrm60kyv.jpg" alt="ListOfInt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once declared as a List&amp;lt;int&amp;gt; we cannot Add() any other type to the list.  This strong typing is where the real power of Generics shines through.&lt;/p&gt;

&lt;p&gt;Lists also dynamically resize.  Simply calling the Add() or AddRange() methods will dynamically resize the list as needed to fit the number of elements.&lt;/p&gt;

&lt;p&gt;Continue to &lt;a href="https://dev.to/seantwie03/generics-in-c-part-2-creating-generic-methods-2pho"&gt;Part Two&lt;/a&gt; to learn how to write your own Generic methods.&lt;/p&gt;

</description>
      <category>generics</category>
    </item>
  </channel>
</rss>
