<?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>Forem: ISeeSharp</title>
    <description>The latest articles on Forem by ISeeSharp (@iseesharp).</description>
    <link>https://forem.com/iseesharp</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%2F380287%2F363bd9ef-73f2-4b8a-bcba-dc4b1ad026a6.png</url>
      <title>Forem: ISeeSharp</title>
      <link>https://forem.com/iseesharp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/iseesharp"/>
    <language>en</language>
    <item>
      <title>The Browser-Based Dev Tools I Actually Use</title>
      <dc:creator>ISeeSharp</dc:creator>
      <pubDate>Sun, 29 Mar 2026 14:22:06 +0000</pubDate>
      <link>https://forem.com/iseesharp/the-browser-based-dev-tools-i-actually-use-2f35</link>
      <guid>https://forem.com/iseesharp/the-browser-based-dev-tools-i-actually-use-2f35</guid>
      <description>&lt;h1&gt;
  
  
  The Browser-Based Dev Tools I Actually Use
&lt;/h1&gt;

&lt;p&gt;I keep a short list of browser tools I can open on any machine with no setup required. No installs, no node_modules, no npm audit warnings. Just a URL. Here are the ones that have actually stuck.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ones I use
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JSON formatting
&lt;/h3&gt;

&lt;p&gt;The JSON Formatter on &lt;a href="https://calchive.tools" rel="noopener noreferrer"&gt;CalcHive&lt;/a&gt; is the one I've settled on. It validates as you type, handles deeply nested objects without issue, and doesn't send your data anywhere (everything runs client-side). That last part matters more than it sounds. If you're working with anything remotely sensitive (and let's be honest, you often are), pasting it into some random web app that logs it server-side is a bad habit.&lt;/p&gt;

&lt;h3&gt;
  
  
  JWT decoding
&lt;/h3&gt;

&lt;p&gt;Every few months I get handed a JWT and need to check what's actually in the payload. Not verify it, just read it. jwt.io is fine but I've started using &lt;a href="https://calchive.tools/encoding-decoding/jwt-decode" rel="noopener noreferrer"&gt;CalcHive's JWT decoder&lt;/a&gt; instead because it keeps everything local and the layout is cleaner. It separates the header, payload, and signature clearly and highlights the expiry timestamp in a way that makes it immediately obvious if the token is expired.&lt;/p&gt;

&lt;p&gt;None of this requires a library. A JWT is just three Base64url-encoded parts separated by dots. But having a UI that just shows it to you instantly saves the mental overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Base64
&lt;/h3&gt;

&lt;p&gt;There are a hundred Base64 tools online and most of them are fine. The one at &lt;a href="https://calchive.tools/encoding-decoding/base64" rel="noopener noreferrer"&gt;calchive.tools/encoding-decoding/base64&lt;/a&gt; handles the edge cases properly: padding, URL-safe variants, encoding binary as well as plain text. I use this probably three or four times a week when dealing with API credentials, image data URIs, or checking what's been embedded in a config somewhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regex testing
&lt;/h3&gt;

&lt;p&gt;Regex is the one area where I genuinely want a full UI with real-time highlighting. Writing regex in code and running tests is fine for production, but when I'm figuring out a pattern for the first time, visual feedback is much faster.&lt;/p&gt;

&lt;p&gt;I've tried Regex101 and it's great, but it's heavier than I sometimes need. For quick checks the &lt;a href="https://calchive.tools/regex-tools/regex-tester" rel="noopener noreferrer"&gt;CalcHive regex tester&lt;/a&gt; gets out of the way and just shows me which parts of my input match. That's usually all I need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unix timestamps
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://calchive.tools/date-time/unix-timestamp" rel="noopener noreferrer"&gt;Unix timestamp converter&lt;/a&gt; takes that number and tells me it's 25 April 2024. Done. You can also go the other way and turn a date into a timestamp, which is useful for database queries and filtering log streams.&lt;/p&gt;

&lt;h3&gt;
  
  
  URL parsing
&lt;/h3&gt;

&lt;p&gt;If you need to break apart a URL and inspect its components (scheme, host, path, query params, fragment), the &lt;a href="https://calchive.tools/network-web/url-parser" rel="noopener noreferrer"&gt;URL parser&lt;/a&gt; does exactly that. It sounds trivial but when you're staring at a redirect URL with eight query parameters and URL encoding layered on top, having it laid out clearly saves you from making a mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cron expressions
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://calchive.tools/date-time/cron-parser" rel="noopener noreferrer"&gt;cron parser&lt;/a&gt; takes an expression like &lt;code&gt;0 9 * * 1-5&lt;/code&gt; and renders it in plain English: "At 09:00 AM, Monday through Friday". That's it. That's the whole tool. It's perfect.&lt;/p&gt;




&lt;h2&gt;
  
  
  A note on "nothing gets uploaded"
&lt;/h2&gt;

&lt;p&gt;I want to come back to this because it's not just a nice-to-have. The CalcHive tools all run entirely in the browser with no server-side processing and no logging of your inputs. For developer tooling this actually matters quite a bit.&lt;/p&gt;

&lt;p&gt;When you paste a JWT into a random tool, you're exposing user data: IDs, email addresses, roles, session info. When you paste JSON from your production database into an online formatter, you might be sending PII to some server you know nothing about. Most of the time nothing bad happens, but it's a risk you're taking for zero benefit because client-side tooling has gotten good enough that it doesn't need a server round trip to format your JSON.&lt;/p&gt;




&lt;h2&gt;
  
  
  A few more worth bookmarking
&lt;/h2&gt;

&lt;p&gt;CalcHive also has a solid set of converters I've found myself using more than expected. The &lt;a href="https://calchive.tools/converters-numbers/number-base" rel="noopener noreferrer"&gt;number base converter&lt;/a&gt; covers binary, octal, decimal and hex all in one place. The &lt;a href="https://calchive.tools/converters-numbers/color-converter" rel="noopener noreferrer"&gt;color converter&lt;/a&gt; handles HEX to RGB to HSL, which I end up needing whenever the design file and the CSS are in different formats. There's also a &lt;a href="https://calchive.tools/generators/uuid-generator" rel="noopener noreferrer"&gt;UUID generator&lt;/a&gt; for when you need v4 UUIDs for test fixtures and don't want to spin up a script for it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The best tool is usually the one that gets out of the way fastest. Single-purpose, well-executed, no friction. That's a decent philosophy for software in general.&lt;/p&gt;

&lt;p&gt;If you've got a favourite dev tool I haven't mentioned, drop it in the comments. Always looking to add to the list.&lt;/p&gt;

</description>
      <category>devtool</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Optimize your C# code with SPAN</title>
      <dc:creator>ISeeSharp</dc:creator>
      <pubDate>Sat, 10 Dec 2022 17:47:11 +0000</pubDate>
      <link>https://forem.com/iseesharp/span-keyword-in-c-n2k</link>
      <guid>https://forem.com/iseesharp/span-keyword-in-c-n2k</guid>
      <description>&lt;p&gt;Span is a struct in C#. A new feature introduced in C# 7.2 that allows for the representation of a contiguous region of arbitrary memory as a first-class object. This can be useful when working with large amounts of data, as it allows for more efficient memory usage and can improve performance.&lt;/p&gt;

&lt;p&gt;Span can be is used to declare a variable of a Span type, where T is the type of the elements in the span. For example, the following code declares a Span variable called numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Span&amp;lt;int&amp;gt; numbers = new int[] { 1, 2, 3, 4, 5 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the main advantages of using Span is that it allows for more efficient memory usage by avoiding unnecessary copying of data. In some cases, using a Span can allow you to access data in memory directly, without having to first copy it to a separate managed array. This can result in improved performance, particularly when working with large amounts of data.&lt;/p&gt;

&lt;p&gt;In addition to providing more efficient memory usage, Span also allows for more convenient manipulation of data. For example, the Slice() method can be used to create a new Span that represents a subset of the original span. This can be useful for accessing specific parts of a larger dataset without having to copy the entire dataset into a new array.&lt;/p&gt;

&lt;p&gt;Here is an example of using the Slice() method to create a new Span that contains only the last three elements of the original numbers span:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Span&amp;lt;int&amp;gt; lastThreeNumbers = numbers.Slice(2, 3);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Usage
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;When working with large datasets, using Span can allow you to access and manipulate the data more efficiently. For example, if you have a large array of integers and you want to perform some operation on every tenth element, you can use the Slice() method to create a new Span that contains only those elements, and then perform the operation on the new span. This can be more efficient than copying the entire array into a new managed array.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// Create a large array of integers
int[] largeArray = new int[10000];

// Fill the array with some values
for (int i = 0; i &amp;lt; largeArray.Length; i++)
{
    largeArray[i] = i;
}

// Create a span that covers the entire array
Span&amp;lt;int&amp;gt; largeArraySpan = largeArray;

// Create a span that covers every tenth element of the array
Span&amp;lt;int&amp;gt; tenthElements = largeArraySpan.Slice(9, largeArraySpan.Length / 10);

// Perform some operation on every tenth element
for (int i = 0; i &amp;lt; tenthElements.Length; i++)
{
    tenthElements[i] *= 2;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The span can be useful when working with data that is stored in memory outside of the managed heap. For example, if you are working with a large byte array that is mapped to a file on disk, you can use a Span to access and manipulate the data directly, without having to first copy it to a managed array.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create a byte array that is mapped to a file on disk
byte[] fileData = File.ReadAllBytes("C:\\largeFile.dat");

// Create a span that covers the entire byte array
Span&amp;lt;byte&amp;gt; fileDataSpan = fileData;

// Use the span to manipulate the data directly
for (int i = 0; i &amp;lt; fileDataSpan.Length; i++)
{
    fileDataSpan[i] ^= 0xFF;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The span can be useful when implementing performance-critical algorithms that require direct access to contiguous regions of memory. For example, if you are implementing a sorting algorithm, you can use a Span to represent the data that needs to be sorted, and then use the span's methods to manipulate the data directly. This can be more efficient than using a managed array, as it allows you to avoid unnecessary copying of data.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create an array of integers to be sorted
int[] data = { 3, 5, 1, 7, 4, 2, 6 };

// Create a span that covers the array
Span&amp;lt;int&amp;gt; dataSpan = data;

// Implement a sorting algorithm using the span
for (int i = 0; i &amp;lt; dataSpan.Length - 1; i++)
{
    for (int j = i + 1; j &amp;lt; dataSpan.Length; j++)
    {
        if (dataSpan[i] &amp;gt; dataSpan[j])
        {
            int temp = dataSpan[i];
            dataSpan[i] = dataSpan[j];
            dataSpan[j] = temp;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please check out my Youtube channel for more C# and .NET content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ"&gt;https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Validation in .NET Core</title>
      <dc:creator>ISeeSharp</dc:creator>
      <pubDate>Sat, 10 Dec 2022 17:29:57 +0000</pubDate>
      <link>https://forem.com/iseesharp/validation-in-net-core-2415</link>
      <guid>https://forem.com/iseesharp/validation-in-net-core-2415</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In .NET Core, validation refers to the process of checking that the data provided by the user or client is in the correct format and meets the requirements of the application. This can include checks for things like required fields, minimum and maximum values, and correct data types.&lt;/p&gt;

&lt;p&gt;To perform validation in a .NET Core API, you can use the built-in ModelState class and the [Required], [Range], and [RegularExpression] attributes. Here is an example of how these can be used to validate the data provided by the user in a controller action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public IActionResult CreateUser([FromBody] User user)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    // Save the user to the database and return a success response...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the CreateUser action method accepts a User object as an argument. The [FromBody] attribute is used to indicate that the User object will be provided in the request body. The if statement at the beginning of the method checks the ModelState to see if the data provided by the user is valid. If the ModelState is not valid, the BadRequest method is called to return an error response to the user.&lt;/p&gt;

&lt;p&gt;The User class itself might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class User
{
    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    [Range(1, 100)]
    public int Age { get; set; }

    [Required]
    [RegularExpression("^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$")]
    public string Email { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this User class, the [Required] attribute is used to indicate that the FirstName, LastName, Age, and Email properties are required and must be provided by the user. The [Range] attribute is used to specify that the Age property must be a number between 1 and 100. Finally, the [RegularExpression] attribute is used to specify that the Email property must match a certain pattern (in this case, a valid email address).&lt;/p&gt;

&lt;p&gt;When the CreateUser action method is called, the ModelState will be checked to ensure that the data provided by the user is valid. If any of the required properties are missing or if any of the properties have invalid values (e.g. if the Age property is not a number between 1 and 100, or if the Email property does not match the specified pattern), the ModelState will be considered invalid and an error response will be returned to the user. Otherwise, the user will be saved to the database and a success response will be returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using [ApiController] to replace the ModelState check
&lt;/h2&gt;

&lt;p&gt;To use the [ApiController] attribute, you simply need to add it to the top of the UsersController class, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ApiController]
public class UsersController : ControllerBase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This attribute indicates that the UsersController class is an API controller, which enables certain features and behaviors that are specific to API controllers in .NET Core. For example, when the [ApiController] attribute is applied to a controller, the ModelState will automatically be checked for validation errors before any action method in the controller is called, and an error response will be returned to the user if any validation errors are found. This means that you don't need to manually check the ModelState in each action method, as the attribute will handle it for you.&lt;/p&gt;

&lt;p&gt;Additionally, the [ApiController] attribute enables the use of HTTP 400 responses for validation errors, rather than the default HTTP 500 responses. This means that when the [ApiController] attribute is applied to a controller, if any validation errors are found, the BadRequest method will automatically be called to return an HTTP 400 response to the user, rather than the InternalServerError method being called to return an HTTP 500 response. This behavior can make it easier to understand and handle validation errors in your API.&lt;/p&gt;

&lt;p&gt;For more C# and Dotnet content see my Youtube channel: &lt;a href="https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ"&gt;https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Improve your C# with YIELD</title>
      <dc:creator>ISeeSharp</dc:creator>
      <pubDate>Sat, 10 Dec 2022 17:18:37 +0000</pubDate>
      <link>https://forem.com/iseesharp/the-yield-keyword-in-c-282e</link>
      <guid>https://forem.com/iseesharp/the-yield-keyword-in-c-282e</guid>
      <description>&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;The yield keyword in C# is used to create an iterator method, which allows the programmer to loop through a collection of items, one at a time. It allows the code inside the iterator method to "yield" each item in the collection, one at a time, rather than returning the entire collection all at once. This can be useful when working with large collections of data, as it allows the programmer to process the data one item at a time, rather than having to load the entire collection into memory all at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Here is an example of how the yield keyword can be used to create an iterator method in C#:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; GetOddNumbers(int start, int end)
{
    for (int i = start; i &amp;lt;= end; i++)
    {
        if (i % 2 != 0)
        {
            yield return i;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the GetOddNumbers method is an iterator method that takes a starting and ending integer as arguments, and yields all of the odd numbers between the starting and ending integers. The yield return statement is used to "return" each odd number in the range to the caller of the method, one at a time.&lt;/p&gt;

&lt;p&gt;To use this iterator method, you could write code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;foreach (int oddNumber in GetOddNumbers(1, 10))
{
    Console.WriteLine(oddNumber);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code would use the foreach loop to iterate over each odd number yielded by the GetOddNumbers iterator method, and print each one to the console.&lt;/p&gt;

&lt;h2&gt;
  
  
  USE CASES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When working with large collections of data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with large collections of data, such as a large list of database records or a large file containing multiple records, using the yield keyword can allow the programmer to process the data one record at a time, rather than having to load the entire collection into memory all at once. This can help to improve the performance and scalability of the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static IEnumerable&amp;lt;DatabaseRecord&amp;gt; GetDatabaseRecords()
{
    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();
        var command = new SqlCommand("SELECT * FROM Records", connection);
        var reader = command.ExecuteReader();
        while (reader.Read())
        {
            yield return new DatabaseRecord(reader);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the GetDatabaseRecords method is an iterator method that yields each DatabaseRecord from a database query one at a time, rather than returning the entire collection of records all at once. This can help to improve the performance and scalability of the application, as it allows the records to be processed one at a time, rather than having to load the entire collection into memory all at once.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When working with infinite sequences or streams of data:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with infinite sequences or streams of data, such as a continuous stream of incoming network traffic or sensor readings, the yield keyword can be used to create an iterator method that yields each piece of data in the sequence as it becomes available, rather than having to wait for the entire sequence to be generated before processing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static IEnumerable&amp;lt;SensorReading&amp;gt; GetSensorReadings()
{
    while (true)
    {
        yield return sensor.GetNextReading();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the GetSensorReadings method is an iterator method that yields each SensorReading from a sensor as it becomes available, rather than having to wait for the entire sequence of readings to be generated before processing them. This allows the application to process the sensor readings as they are generated, rather than having to wait for the entire sequence to be generated before processing it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When working with algorithms that generate sequences of data:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with algorithms that generate sequences of data, such as algorithms that generate sequences of random numbers or prime numbers, the yield keyword can be used to create an iterator method that yields each element in the generated sequence as it is produced, rather than having to generate the entire sequence at once and return it to the caller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static IEnumerable&amp;lt;int&amp;gt; GetRandomNumbers(int min, int max)
{
    Random random = new Random();
    while (true)
    {
        yield return random.Next(min, max);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the GetRandomNumbers method is an iterator method that yields a sequence of random numbers. The yield return statement is used to "return" each random number in the sequence as it is generated, rather than generating the entire sequence at once and returning it to the caller. This allows the application to process the random numbers as they are generated, rather than having to wait for the entire sequence to be generated before processing it.&lt;/p&gt;

&lt;p&gt;Please check out my Youtube channel for more C# and .NET content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCfZF4WWaH4i13MzEICLt6sQ&lt;/a&gt;&lt;/p&gt;

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