<?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: Vanderlei Adriano Morais</title>
    <description>The latest articles on DEV Community by Vanderlei Adriano Morais (@vanderlei-dev).</description>
    <link>https://dev.to/vanderlei-dev</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%2F965506%2F6b70a765-3b63-4ee1-b55b-727be0584cd8.jpeg</url>
      <title>DEV Community: Vanderlei Adriano Morais</title>
      <link>https://dev.to/vanderlei-dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vanderlei-dev"/>
    <language>en</language>
    <item>
      <title>A Visual Studio extension to quickly switch startup class</title>
      <dc:creator>Vanderlei Adriano Morais</dc:creator>
      <pubDate>Wed, 09 Apr 2025 15:11:57 +0000</pubDate>
      <link>https://dev.to/vanderlei-dev/a-visual-studio-extension-to-quickly-switch-startup-class-4n8e</link>
      <guid>https://dev.to/vanderlei-dev/a-visual-studio-extension-to-quickly-switch-startup-class-4n8e</guid>
      <description>&lt;p&gt;Have you ever wanted to set multiple entry points in a C# project to quickly switch between different programs? Well, it's not so simple—that's why I developed a Visual Studio Extension to help with that.&lt;/p&gt;

&lt;p&gt;"Change Startup Object" is a lightweight extension that adds a new "Set as Startup Object" command to context menus. With it, you can easily change which class serves as the entry point of your project.&lt;/p&gt;

&lt;p&gt;This command is similar to "Set as Startup Project" but is designed for setting a class as an entry point at the project level, allowing multiple &lt;code&gt;Main&lt;/code&gt; methods across different &lt;code&gt;.cs&lt;/code&gt; files. &lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;When the command is executed, the selected class is set in the respective project as the &lt;code&gt;&amp;lt;StartupObject&amp;gt;&lt;/code&gt;. This is a &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/advanced#mainentrypoint-or-startupobject" rel="noopener noreferrer"&gt;compiler option&lt;/a&gt; that specifies the entry point of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shortcut
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;Alt+F5&lt;/code&gt; to set the active file OR the selected file in Solution Explorer as the Startup Object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When you don't want to create multiple projects just to have different entry points, such as small POCs and benchmarks using Console Applications.
&lt;/li&gt;
&lt;li&gt;A quick solution for &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0017" rel="noopener noreferrer"&gt;CS0017&lt;/a&gt; that eliminates the need to compile with the &lt;code&gt;/main&lt;/code&gt; option.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Doesn't work with &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements#only-one-top-level-file" rel="noopener noreferrer"&gt;top-level statements&lt;/a&gt;, since there is a limitation of only one top-level file per application.&lt;/li&gt;
&lt;li&gt;The selected class must have a &lt;code&gt;Main&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Download and install
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get it in &lt;a href="https://marketplace.visualstudio.com/items?itemName=vanderlei-dev.changeStartup2022" rel="noopener noreferrer"&gt;Visual Studio Marketplace&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run and install the VSIX file.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>visualstudio</category>
      <category>csharp</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Improving String Manipulation in .NET</title>
      <dc:creator>Vanderlei Adriano Morais</dc:creator>
      <pubDate>Wed, 25 Sep 2024 03:08:20 +0000</pubDate>
      <link>https://dev.to/vanderlei-dev/improving-string-manipulation-in-net-4654</link>
      <guid>https://dev.to/vanderlei-dev/improving-string-manipulation-in-net-4654</guid>
      <description>&lt;p&gt;One thing so trivial as transforming a string could have considerable impact in the performance depending on how is implemented. Let's check an example of a simple requirement that I had to work some time ago.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Requirement
&lt;/h3&gt;

&lt;p&gt;Given a "CPF" (Brazilian National ID) stored as string with only numeric digits, add some standard separators (“.” and “-”) to display it in a more user-friendly format, pretty straightforward as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Input: “12345678909”  
&amp;gt; Output: “123.456.789–09”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initial Solution: Stack Overflow
&lt;/h3&gt;

&lt;p&gt;Like a good developer I google it for a quick solution and, of course, I ended up in Stack Overflow. In the best voted answer, I found this implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToUInt64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"000\.000\.000\-00"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like a good solution, right? To use the number format string - that allows defining a mask for a number in the &lt;code&gt;ToString&lt;/code&gt; method - the string was converted to &lt;code&gt;UInt64&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pretty clever, huh? Not much...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  My Solution
&lt;/h3&gt;

&lt;p&gt;I had doubts about the performance of the solution found, especially because the conversion part, so I tried to implement my own solution in a very simple way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;      
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, I just used &lt;code&gt;Substring&lt;/code&gt; to split the CPF into four parts, inserting the corresponding separators. &lt;/p&gt;

&lt;p&gt;Then, to compare the approaches I used &lt;em&gt;Benchmark.DotNet&lt;/em&gt;, here are the results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FormatCpfConvert&lt;/td&gt;
&lt;td&gt;301.97 ns&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FormatCpfSubstring&lt;/td&gt;
&lt;td&gt;127.54 ns&lt;/td&gt;
&lt;td&gt;-56%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;My solution was 50% faster than the Stack Overflow one!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Final Solution
&lt;/h3&gt;

&lt;p&gt;Even that my solution was an acceptable implementation I felt it could still be improved, the problem is that using &lt;code&gt;Substring&lt;/code&gt; for extracting the CPF sections generates new allocations in the memory for each part of the string.&lt;/p&gt;

&lt;p&gt;To make this process efficiently instead of creating new &lt;em&gt;substrings&lt;/em&gt; we ideally could just pick &lt;em&gt;slices&lt;/em&gt; of the original input and add the required separators. Here is where the power of &lt;em&gt;Span&lt;/em&gt; and &lt;em&gt;Slice&lt;/em&gt; can be used.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; type provides a way to point to a specific part of an object in the memory by using the &lt;code&gt;Slice&lt;/code&gt; method, for manipulating strings this can be very helpful in scenarios where parts of the existing string can be used to produce the desired result.&lt;/p&gt;

&lt;p&gt;So, by just applying the extension method &lt;code&gt;AsSpan&lt;/code&gt; into the string and using &lt;code&gt;Slice&lt;/code&gt; I implemented this new solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cpfAsSpan&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsSpan&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpfAsSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpfAsSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpfAsSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cpfAsSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the benchmark again, we have:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FormatCpfConvert&lt;/td&gt;
&lt;td&gt;301.97 ns&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FormatCpfSubstring&lt;/td&gt;
&lt;td&gt;127.54 ns&lt;/td&gt;
&lt;td&gt;-56%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FormatCpfAsSpan&lt;/td&gt;
&lt;td&gt;75.94 ns&lt;/td&gt;
&lt;td&gt;-74%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Final solution is almost 75% faster than the initial one!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this gives you an idea of &lt;code&gt;Span&lt;/code&gt; type and its benefits regarding performance. Although this type was introduced a few years ago is not common to see it being used or explained. &lt;/p&gt;

&lt;p&gt;Also, this experience reinforced practices that I recommend and try to follow every day:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stay up to date about the features of the programming language/framework that you are working with, you never know when you can find something useful to apply in your day-to-day activities&lt;/li&gt;
&lt;li&gt;Make it work, then make it better/faster&lt;/li&gt;
&lt;li&gt;Don't blindly rely on solutions from the internet&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/january/csharp-all-about-span-exploring-a-new-net-mainstay" rel="noopener noreferrer"&gt;Microsoft Magazine - All about Span&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://pt.stackoverflow.com/questions/75498/formatar-uma-string-de-cpf" rel="noopener noreferrer"&gt;StackOverflow - Format a CPF string&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>performance</category>
      <category>benchmark</category>
    </item>
  </channel>
</rss>
