<?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: Roberto Higor</title>
    <description>The latest articles on DEV Community by Roberto Higor (@robertohigor).</description>
    <link>https://dev.to/robertohigor</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%2F592480%2Ffc53bddc-5160-41d8-a5b5-204be6e13ed8.jpeg</url>
      <title>DEV Community: Roberto Higor</title>
      <link>https://dev.to/robertohigor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robertohigor"/>
    <language>en</language>
    <item>
      <title>Injeção de dependência e inversão de controle</title>
      <dc:creator>Roberto Higor</dc:creator>
      <pubDate>Sun, 26 Mar 2023 23:40:32 +0000</pubDate>
      <link>https://dev.to/robertohigor/injecao-de-dependencia-e-inversao-de-controle-1ojf</link>
      <guid>https://dev.to/robertohigor/injecao-de-dependencia-e-inversao-de-controle-1ojf</guid>
      <description>&lt;h2&gt;
  
  
  Dependência
&lt;/h2&gt;

&lt;p&gt;Uma dependência é quando uma classe depende de outra para realizar uma função, de forma a utilizar um recurso. Digamos que em uma aplicação que possui um componente de edição de textos, você quer adicionar a funcionalidade de verificação ortográfica, por exemplo:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a5v9l3t7o36k0yo6c20.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a5v9l3t7o36k0yo6c20.jpg" alt="Dependência simples"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No diagrama acima, o &lt;code&gt;SpellChecker&lt;/code&gt; é uma dependência de &lt;code&gt;TextEditor&lt;/code&gt;. A &lt;strong&gt;classe TextEditor está dependendo diretamente de &lt;code&gt;SpellCHecker&lt;/code&gt;&lt;/strong&gt;, tendo a responsabilidade de instânciar e chamar a outra classe.&lt;/p&gt;

&lt;p&gt;Isso permite a reutilização dessa funcionalidade por outras classes, porém gera um acoplamento forte entre as classes, sendo representado no código abaixo:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextEditor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;SpellChecker&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;checker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SpellChecker&lt;/span&gt;&lt;span class="p"&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;h2&gt;
  
  
  Inversão de controle
&lt;/h2&gt;

&lt;p&gt;Inversão de controle é uma técnica em que o controle é invertido na hierarquia de dependência entre as classes. Isso significa que uma classe dependente recebe suas dependências de uam classe externa, ao invés de cria-las internamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Orientação a interfaces
&lt;/h3&gt;

&lt;p&gt;No primeiro exemplo, é gerado diversos problemas devido ao acoplamento a uma classe concreta, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para substituir a classe &lt;code&gt;SpellChecker&lt;/code&gt; com uma implementação diferente, é preciso alterar a classe TextEditor;&lt;/li&gt;
&lt;li&gt;Caso &lt;code&gt;SpellChecker&lt;/code&gt; tenha outras dependências, elas precisam ser configuradas pela classe &lt;code&gt;TextEditor&lt;/code&gt;. Isso resulta em um código de configuração espalhado caso várias classes do sistema utilizem o &lt;code&gt;SpellChecker&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Não é possível criar mocks para testes unitários, por depender da implementação de &lt;code&gt;SpellChecker&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para resolver parte do acoplamento, o primeiro passo para reduzir o acoplamento é através do design &lt;strong&gt;orientado a interfaces&lt;/strong&gt;. Com uma classe orientada a interfaces, é possível a alteração de uma implementação sem que afeta a classe que utilize essa dependência.&lt;/p&gt;

&lt;p&gt;Um segundo passo é transferir a responsabilidade de criar os objetos das dependências para quem utiliza a classe, tendo ela então a responsabilidade de injetar a dependência, não mais o &lt;code&gt;TextEditor&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1vh8fu9h4j028scklmi.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1vh8fu9h4j028scklmi.jpg" alt="Diagrama injeção de dependência"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O diagrama acima mostra a utilização do TextEditor por uma outra classe (como a classe Main), tendo o controle sobre qual implentação da interface ISpellChecker utilizar, fornecendo-a antes de utilizar em si a TextEditor.&lt;/p&gt;

&lt;p&gt;Adaptando o exemplo acima, a classe &lt;code&gt;TextEditor&lt;/code&gt; deve depender da interface de SpellChecker, e não mais da implementação. Além disso, ela deve dar a responsabilidade de injetar a implementação para outra classe, nesse exemplo é utilizado a injeção via construtor:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextEditor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ISpellCHecker&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISpellCHecker&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;checker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&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;Já o código para utilização da classe (caso não utilizar um framework para ajudar):&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="n"&gt;ISpellChecker&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SpellChecker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Implementação de ISpellChecker&lt;/span&gt;
&lt;span class="n"&gt;TextEditor&lt;/span&gt; &lt;span class="n"&gt;textEditor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;textoOk&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textEditor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Check&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Injeção de dependências
&lt;/h2&gt;

&lt;p&gt;Conforme um sistema vai crescendo, a criação de vários objetos pode se tornar um processo complexo e trabalhoso. Uma maneira é tornar necessário apenas com que o componente solicite a dependência, e não mais o fornecimento por um componente. Isso é possível através da &lt;strong&gt;injeção de dependência&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A injeção de dependência (ou &lt;em&gt;dependency injection&lt;/em&gt;) é uma &lt;em&gt;design pattern&lt;/em&gt; para sistemas com orientação a objetos, sendo uma &lt;strong&gt;especialização de inversão de controle tendo (IoC)&lt;/strong&gt; o objetivo de injetar dinamicamente dependências em uma classe, em tempo de execução. Nesse caso, a responsabilidade de construir os objetos para um framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos de injeção de dependência
&lt;/h3&gt;

&lt;p&gt;Mesmo utilizando um framework para o fornecimento de dependências, é necessário com que a classe tenha uma maneira de receber essa implementação. O método utilizado servirá tanto com o uso do framework, quanto para uma injeção manual, sendo as 2 principais maneiras:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Injeção via construtor&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;É o exemplo utilizado acima, onde para construir uma instância de &lt;code&gt;TextEditor&lt;/code&gt;, é obrigado fornecer uma implementação de &lt;code&gt;ISpellChecker&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Injeção via Setter&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para esse caso, após instanciar a classe, a injeção é realizada via um método set, por exemplo:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TextEditor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ISpellChecker&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;SetSpellChecker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ISpellChecker&lt;/span&gt; &lt;span class="n"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;checker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;checker&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;h3&gt;
  
  
  Service Container do ASP.NET Core
&lt;/h3&gt;

&lt;p&gt;O ASP.NET Core possui um &lt;strong&gt;container de serviços&lt;/strong&gt;, onde é possível registrar as dependências. O .NET ficará responsável por criar e eliminar instâncias da dependência onde for necessário. &lt;strong&gt;É a partir dele que iremos aplicar a injeção de dependência&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;ele torna mais fácil a configuração de implementações, ao invés de levar a responsabilidade de fornecer manualmente a implementação para uma classe, antes de conseguir utiliza-la, o que pode ser um processo demorado.&lt;/p&gt;

&lt;p&gt;No container de serviços, é qual implementação de cada interface utilizar. Dessa forma, quando uma nova instância é requisitada, ele automaticamente resolve as dependências.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ciclo de vida de uma dependência
&lt;/h3&gt;

&lt;p&gt;Uma das principais vantagens da utilização de um container de IoC é o controle do ciclo de vida da instância da dependência, sem com que o desenvolvedor se preocupe em desenvolver essa lógica. &lt;/p&gt;

&lt;p&gt;A escolha do ciclo de vida é realizada na etapa do registro da implementação, sendo os ciclos disponíveis no C#:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Singleton - Uma instância compartilhada por todas as requisições;&lt;/li&gt;
&lt;li&gt;Scoped - Uma instância por requisição;&lt;/li&gt;
&lt;li&gt;Transient - Uma instância por chamada, sendo sempre diferentes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Transferindo para código, cada forma ficaria da seguinte maneira:&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="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyDependency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Myependency&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Singleton&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScoped&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyDependency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Myependency&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Scoped&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddTransient&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMyDependency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Myependency&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Transient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existem casos específicos de quando usar cada uma das implementações. Por exemplo, &lt;code&gt;Singleton&lt;/code&gt; pode ser ideal para classes de &lt;code&gt;cache&lt;/code&gt;, por ser acessadas em todas as requisições. Essas diferenças e seus casos de uso serão discutidos no próximo artigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A inversão de controle é uma forma com que conseguimos injetar as dependências de uma classe através de uma classe externa, que junto do &lt;em&gt;design&lt;/em&gt; orientado a interfaces, Ajuda na redução de acoplamento entre as classes.&lt;/p&gt;

&lt;p&gt;Já a injeção de dependência, é um tipo de IoC no qual registramos o ciclo de vida e implementação de uma interface, transferindo a responsabilidade de criação de objetos para um framework, e eliminando a necessidade de criar manualmente cada objetos, o que pode se tornar complexo em sistemas grandes.&lt;/p&gt;

&lt;p&gt;Caso tenha alguma informação incorreta, ou algum ponto a acrescentar, não deixe de comentar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fontes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/3058/what-is-inversion-of-control" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/3058/what-is-inversion-of-control&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/tags/dependency-injection/info" rel="noopener noreferrer"&gt;https://stackoverflow.com/tags/dependency-injection/info&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/130794/what-is-dependency-injection" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/130794/what-is-dependency-injection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/4596300/where-exactly-is-the-difference-between-ioc-and-di" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/4596300/where-exactly-is-the-difference-between-ioc-and-di&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/previous-versions/msp-n-p/ff921087(v=pandp.10)" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/previous-versions/msp-n-p/ff921087(v=pandp.10)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imasters.com.br/software/inversao-de-controle-service-locator-e-injecao-de-dependencia" rel="noopener noreferrer"&gt;https://imasters.com.br/software/inversao-de-controle-service-locator-e-injecao-de-dependencia&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>designpatterns</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Porque você precisa conhecer o StringBuilder</title>
      <dc:creator>Roberto Higor</dc:creator>
      <pubDate>Thu, 09 Mar 2023 00:21:06 +0000</pubDate>
      <link>https://dev.to/robertohigor/por-que-voce-deve-dar-atencao-ao-stringbuilder-558g</link>
      <guid>https://dev.to/robertohigor/por-que-voce-deve-dar-atencao-ao-stringbuilder-558g</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Nesse artigo vou explicar as vantagens e diferenças entre a classe &lt;code&gt;StringBuilder&lt;/code&gt; e a concatenação de strings com "+". Por ser uma ferramenta muito utilizada no dia a dia, é importante entender as diferenças de como as duas funcionam internamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutável vs Imutável
&lt;/h2&gt;

&lt;p&gt;A classe &lt;code&gt;String&lt;/code&gt; é do tipo imutável, ou seja, após criado seu valor não pode ser alterado. Apesar de parecer que ao adicionar uma string a outra existente, estamos apenas incrementando a variável anterior com mais valores, na realidade é alocado e criado uma nova variável na memória contendo a junção das duas strings, por exemplo:&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="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Olá, "&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;mundo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Mundo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Internamente está sendo criado uma nova string e &lt;/span&gt;
&lt;span class="c1"&gt;// alocado na variável já existente.&lt;/span&gt;
&lt;span class="n"&gt;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;mundo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Internamente, o compilador converte a operação "+" em &lt;code&gt;String&lt;/code&gt;.Concat&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para processos onde é realizado manipulações em string em um alto volume, isso pode resultar em um impacto tanto na performance quanto no uso de memória, por ser necessário uma nova alocação a cada concatenação, resultando também em chamadas excessivas ao Garbage Collector.&lt;/p&gt;

&lt;p&gt;Para casos onde precisamos de uma variável mutável, a alternativa é a classe &lt;code&gt;StringBuilder&lt;/code&gt; que, diferente da &lt;code&gt;String&lt;/code&gt;, trabalha com dados mutáveis. Ou seja, uma instância do StringBuilder pode ser modificada (incrementadas, substituidas etc) sem precisar criar uma nova instância. Essa é sua principal vantagem, que é feito através do uso de um buffer interno, no qual permite com que o valor da string aumente e diminua.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buffer
&lt;/h3&gt;

&lt;p&gt;Diferente da &lt;code&gt;String&lt;/code&gt;, o &lt;code&gt;StringBuilder&lt;/code&gt; trabalha com um buffer para acomodar as modificações. Caso o buffer se esgote, será alocado um buffer maior, copiando os dados do buffer antigo. A alocação padrão do StringBuilder comporta 16 caracteres, tendo o máximo o valor da constante Int32.MaxValue, que ao atigindo, resulta em um OutOfMemoryException.&lt;/p&gt;

&lt;p&gt;Para reduzir a frequência no qual é alocado mais memória para o buffer interno, pode-se utilizar o construtor que recebe o tamanho da memória no qual queremos alocar (em caracteres)&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="c1"&gt;// Inicia stringbuilder com tamanho para 100 caracteres&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É dito que uma alocação exata pode trazer uma melhorias na performance e redução na alocação de memória, no entanto nos exemplos realizados a versão com Buffer após um certo volume de dados trouxe performance pior do que a versão sem buffer.&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderLoop1kComBufferTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="s"&gt;"Mundo"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderLoop1kSemBufferTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderLoop10kComBufferTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="s"&gt;"Mundo"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderLoop10kSemBufferTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Gen1&lt;/th&gt;
&lt;th&gt;Gen2&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop1kComBufferTest&lt;/td&gt;
&lt;td&gt;3.846 us&lt;/td&gt;
&lt;td&gt;0.0176 us&lt;/td&gt;
&lt;td&gt;0.0156 us&lt;/td&gt;
&lt;td&gt;1.8005&lt;/td&gt;
&lt;td&gt;0.1144&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;29.47 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop1kSemBufferTest&lt;/td&gt;
&lt;td&gt;4.383 us&lt;/td&gt;
&lt;td&gt;0.0256 us&lt;/td&gt;
&lt;td&gt;0.0214 us&lt;/td&gt;
&lt;td&gt;1.6174&lt;/td&gt;
&lt;td&gt;0.0916&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;26.5 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop10kComBufferTest&lt;/td&gt;
&lt;td&gt;94.036 us&lt;/td&gt;
&lt;td&gt;0.4714 us&lt;/td&gt;
&lt;td&gt;0.4410 us&lt;/td&gt;
&lt;td&gt;62.3779&lt;/td&gt;
&lt;td&gt;62.3779&lt;/td&gt;
&lt;td&gt;62.3779&lt;/td&gt;
&lt;td&gt;211.13 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop10kSemBufferTest&lt;/td&gt;
&lt;td&gt;70.643 us&lt;/td&gt;
&lt;td&gt;0.9460 us&lt;/td&gt;
&lt;td&gt;0.8386 us&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;208.57 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Para a execução do método Append() mil vezes, a versão com buffer teve uma performance um pouco melhor. No entanto, para a versão de 10 mil vezes, a performance foi consideravelmente pior.&lt;/p&gt;

&lt;h3&gt;
  
  
  AppendJoin vs Join
&lt;/h3&gt;

&lt;p&gt;Ambas as classes possuem também métodos de Join, sendo StringBuilder.AppendJoin e String.Join. Para casos onde temos um array de strings, o string.Concat pode ser uma alternativa melhor por conseguir determinar o tamanho final da string ao examinar o array. &lt;/p&gt;

&lt;p&gt;Em casos onde é necessário chamar várias vezes (como em um loop), o AppendJoin consegue se sair melhor pela vantagem da imutabilidade.&lt;/p&gt;

&lt;p&gt;O StringBuilder.AppendJoin é uma combinação entre o String.Join e o StringBuilder.Append, por chamar o Append internamente. Para cada valor, também é chamado o ToString(), o que pode ser ruim para valores que não são string (como int e decimal).&lt;/p&gt;

&lt;p&gt;A comparação pode ser vista no benchmark abaixo:&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;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;_dataList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllLines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"randomString200-1.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderJoin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AppendJoin&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;_dataList&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringJoin&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;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&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;_dataList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringConcat&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;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_dataList&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;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;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Gen1&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderJoin&lt;/td&gt;
&lt;td&gt;4.041 us&lt;/td&gt;
&lt;td&gt;0.0410 us&lt;/td&gt;
&lt;td&gt;0.0383 us&lt;/td&gt;
&lt;td&gt;5.1193&lt;/td&gt;
&lt;td&gt;0.8469&lt;/td&gt;
&lt;td&gt;83.71 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringJoin&lt;/td&gt;
&lt;td&gt;2.363 us&lt;/td&gt;
&lt;td&gt;0.0460 us&lt;/td&gt;
&lt;td&gt;0.0644 us&lt;/td&gt;
&lt;td&gt;2.0523&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;33.69 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcat&lt;/td&gt;
&lt;td&gt;1.686 us&lt;/td&gt;
&lt;td&gt;0.0127 us&lt;/td&gt;
&lt;td&gt;0.0119 us&lt;/td&gt;
&lt;td&gt;2.0523&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;33.69 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Nesse caso o String.Concat teve uma performance melhor (pelo fato do exemplo utilizar um array), além de alocar menos memoria do que o StringBuilder.Join. Em seguida vem o StringJoin.&lt;/p&gt;

&lt;p&gt;Para os cenários de Array com tamanho fixo, o próprio String.Concat consegue se sair melhor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando utilizar
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;StringBuilder&lt;/code&gt; é recomendado quando se utiliza um alto volume de concatenações de string, como por exemplo em um loop. &lt;a href="https://learn.microsoft.com/pt-br/dotnet/api/system.text.stringbuilder?view=net-7.0#the-string-and-stringbuilder-types"&gt;Segundo a microsoft&lt;/a&gt;, a classe &lt;code&gt;String&lt;/code&gt; deve ser utilizada em casos de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando o número de modificações na string for pequeno;&lt;/li&gt;
&lt;li&gt;Quando é realizado um número fixo de concatenações, pois nesse caso o compilador pode combinar em uma única operação;&lt;/li&gt;
&lt;li&gt;Quando é necessário utilizar métodos de pesquisas como IndesOf ou StartsWith, pelo fato do &lt;code&gt;StringBuilder&lt;/code&gt; não suportar sem antes o converter em &lt;code&gt;String&lt;/code&gt;, o que negaria seus benefícios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Já para o caso de uso do &lt;code&gt;StringBuilder&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando o código pode fazer um número desconhecido de modificações (como em loops);&lt;/li&gt;
&lt;li&gt;Quando o código fará um número significativo de alterações em uma string.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao realizar a concatenação de uma palavra 100 mil vezes, a vantagem do &lt;code&gt;StringBuilder&lt;/code&gt; fica bem evidente:&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderLoopTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringConcatLoopTest&lt;/span&gt;&lt;span class="p"&gt;()&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;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Olá, "&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;mundo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Mundo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="n"&gt;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;mundo&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;textoOriginal&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;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;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Gen1&lt;/th&gt;
&lt;th&gt;Gen2&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderTest&lt;/td&gt;
&lt;td&gt;18.642 ns&lt;/td&gt;
&lt;td&gt;0.3487 ns&lt;/td&gt;
&lt;td&gt;0.3261 ns&lt;/td&gt;
&lt;td&gt;0.0091&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;152 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatTest&lt;/td&gt;
&lt;td&gt;8.216 ns&lt;/td&gt;
&lt;td&gt;0.0610 ns&lt;/td&gt;
&lt;td&gt;0.0571 ns&lt;/td&gt;
&lt;td&gt;0.0029&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;48 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoopTest&lt;/td&gt;
&lt;td&gt;699,651.201 ns&lt;/td&gt;
&lt;td&gt;2,971.4637 ns&lt;/td&gt;
&lt;td&gt;2,779.5089 ns&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;2013684 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatLoopTest&lt;/td&gt;
&lt;td&gt;5,013,108,142.857 ns&lt;/td&gt;
&lt;td&gt;24,203,777.6872 ns&lt;/td&gt;
&lt;td&gt;21,456,018.4848 ns&lt;/td&gt;
&lt;td&gt;11800000.0000&lt;/td&gt;
&lt;td&gt;11779000.0000&lt;/td&gt;
&lt;td&gt;11776000.0000&lt;/td&gt;
&lt;td&gt;50007779072 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Além do menor tempo de execução e memória alocada, com o &lt;code&gt;StringBuilder&lt;/code&gt; houve menos chamadas ao Garbage Collector Gen 0, devido ao fato da concatenação alocar mais memória ao criar novos objetos de string, resultando em mais chamadas ao GC Generation 0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando não utilizar
&lt;/h2&gt;

&lt;p&gt;Para strings pequenas, o &lt;code&gt;StringBuilder&lt;/code&gt; pode não trazer um ganho muito significativo de memória, além de que utilizar o "+=" nesses casos possuí uma sintaxe mais simples e rápida de se desenvolver. &lt;/p&gt;

&lt;p&gt;Outro caso é quando já existe um array de strings de tamanho definido, como citado no capítulo sobre Join, em que o String.Concat consegue determinar de uma vez o quanto é preciso alocado.&lt;/p&gt;

&lt;p&gt;Exemplo de quando não utilizar:&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;using&lt;/span&gt; &lt;span class="nn"&gt;System.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BenchmarkDotNet.Attributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Domain.Benchmark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MemoryDiagnoser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StringBuilderBenchmark&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringBuilderTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;StringBuilder&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;stringBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;stringBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mundo"&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;stringBuilder&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="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;StringConcatTest&lt;/span&gt;&lt;span class="p"&gt;()&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;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Olá, "&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;mundo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Mundo"&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;textoOriginal&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;mundo&lt;/span&gt;&lt;span class="p"&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;Nesse caso, o &lt;code&gt;StringBuilder&lt;/code&gt; além de ter sido mais lento, alocou mais memória do que a concatenação normal.&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;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderTest&lt;/td&gt;
&lt;td&gt;18.626 ns&lt;/td&gt;
&lt;td&gt;0.1947 ns&lt;/td&gt;
&lt;td&gt;0.1726 ns&lt;/td&gt;
&lt;td&gt;0.0091&lt;/td&gt;
&lt;td&gt;152 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatTest&lt;/td&gt;
&lt;td&gt;8.320 ns&lt;/td&gt;
&lt;td&gt;0.0479 ns&lt;/td&gt;
&lt;td&gt;0.0425 ns&lt;/td&gt;
&lt;td&gt;0.0029&lt;/td&gt;
&lt;td&gt;48 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Esse artigo buscou mostrar de forma breve as vantagens e quando utilizar a classe &lt;code&gt;StringBuilder&lt;/code&gt;, sendo uma grande aliada na performance de sistemas que executem um grande volume de concatenações de string. Seu uso deve ser mais para casos onde não sabemos o tamanho da string, pela sua propriedade de ser mutável. Em casos em que sabemos o tamanho, como ao juntar um array de strings, o string.Concat consegue uma vantagem.&lt;/p&gt;

&lt;p&gt;Seguem os resultados dos benchmarks com tamanhos de string variados:&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;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Gen1&lt;/th&gt;
&lt;th&gt;Gen2&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderTest&lt;/td&gt;
&lt;td&gt;19.107 ns&lt;/td&gt;
&lt;td&gt;0.2487 ns&lt;/td&gt;
&lt;td&gt;0.2205 ns&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.0091&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;152 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatTest&lt;/td&gt;
&lt;td&gt;8.414 ns&lt;/td&gt;
&lt;td&gt;0.1637 ns&lt;/td&gt;
&lt;td&gt;0.1531 ns&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.0029&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;48 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop1kTest&lt;/td&gt;
&lt;td&gt;4,503.729 ns&lt;/td&gt;
&lt;td&gt;85.7993 ns&lt;/td&gt;
&lt;td&gt;80.2567 ns&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1.6174&lt;/td&gt;
&lt;td&gt;0.0916&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;27136 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatLoop1kTest&lt;/td&gt;
&lt;td&gt;161,308.281 ns&lt;/td&gt;
&lt;td&gt;3,194.8901 ns&lt;/td&gt;
&lt;td&gt;4,154.2595 ns&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;301.2695&lt;/td&gt;
&lt;td&gt;7.5684&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;5040000 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop10kTest&lt;/td&gt;
&lt;td&gt;70,641.925 ns&lt;/td&gt;
&lt;td&gt;698.0930 ns&lt;/td&gt;
&lt;td&gt;652.9966 ns&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;31.1279&lt;/td&gt;
&lt;td&gt;213579 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatLoop10kTest&lt;/td&gt;
&lt;td&gt;20,383,109.233 ns&lt;/td&gt;
&lt;td&gt;400,692.3340 ns&lt;/td&gt;
&lt;td&gt;492,086.1706 ns&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;64593.7500&lt;/td&gt;
&lt;td&gt;46625.0000&lt;/td&gt;
&lt;td&gt;43625.0000&lt;/td&gt;
&lt;td&gt;500414677 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringBuilderLoop100kTest&lt;/td&gt;
&lt;td&gt;709,105.225 ns&lt;/td&gt;
&lt;td&gt;7,222.7404 ns&lt;/td&gt;
&lt;td&gt;6,402.7713 ns&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;249.0234&lt;/td&gt;
&lt;td&gt;2013684 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringConcatLoop100kTest&lt;/td&gt;
&lt;td&gt;5,111,168,506.667 ns&lt;/td&gt;
&lt;td&gt;76,749,055.3313 ns&lt;/td&gt;
&lt;td&gt;71,791,113.9755 ns&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;11783000.0000&lt;/td&gt;
&lt;td&gt;11762000.0000&lt;/td&gt;
&lt;td&gt;11759000.0000&lt;/td&gt;
&lt;td&gt;50007763560 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Fonte
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.stevejgordon.co.uk/creating-strings-with-no-allocation-overhead-using-string-create-csharp"&gt;https://www.stevejgordon.co.uk/creating-strings-with-no-allocation-overhead-using-string-create-csharp&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/pt-br/dotnet/api/system.text.stringbuilder?view=net-7.0#the-string-and-stringbuilder-types"&gt;https://learn.microsoft.com/pt-br/dotnet/api/system.text.stringbuilder?view=net-7.0#the-string-and-stringbuilder-types&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/c-sharp-progarmming/stringbuilder-vs-concatenation-in-net-b817ccec331e"&gt;https://medium.com/c-sharp-progarmming/stringbuilder-vs-concatenation-in-net-b817ccec331e&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.macoratti.net/21/11/c_benchmark1.htm"&gt;https://www.macoratti.net/21/11/c_benchmark1.htm&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.oreilly.com/library/view/c-cookbook/0596003390/ch02s22.html"&gt;https://www.oreilly.com/library/view/c-cookbook/0596003390/ch02s22.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.infoworld.com/article/3616600/when-to-use-string-vs-stringbuilder-in-net-core.html"&gt;https://www.infoworld.com/article/3616600/when-to-use-string-vs-stringbuilder-in-net-core.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://davecallan.com/improve-performance-stringbuilder-dotnet-setting-capacity/"&gt;https://davecallan.com/improve-performance-stringbuilder-dotnet-setting-capacity/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://andrewlock.net/a-deep-dive-on-stringbuilder-part-2-appending-strings-built-in-types-and-lists/"&gt;https://andrewlock.net/a-deep-dive-on-stringbuilder-part-2-appending-strings-built-in-types-and-lists/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>net</category>
      <category>stringbuilder</category>
      <category>performance</category>
    </item>
    <item>
      <title>Retornando dado específico  em API REST ASP.NET Core</title>
      <dc:creator>Roberto Higor</dc:creator>
      <pubDate>Sun, 21 Mar 2021 03:31:28 +0000</pubDate>
      <link>https://dev.to/robertohigor/retornando-dado-especifico-na-api-48pl</link>
      <guid>https://dev.to/robertohigor/retornando-dado-especifico-na-api-48pl</guid>
      <description>&lt;p&gt;Existem algumas diferenças entre a rota de listagem de todos os dados e da listagem específica. Entre elas, as duas que se destacam são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Precisamos receber um parâmetro indicando qual objeto retoranr&lt;/li&gt;
&lt;li&gt;Precisamos verificar se o objeto existe ou não para que seja retornada uma mensagem de erro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma rota para retornar um objeto do tipo &lt;code&gt;Palavra&lt;/code&gt;, sendo especificado pelo seu &lt;code&gt;id&lt;/code&gt; recebe a seguinte anotação:&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="n"&gt;Palavra&lt;/span&gt; &lt;span class="nf"&gt;GetPalavra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&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;Estamos dizendo pro ASP.NET core que nossa rota irá receber um parâmetro, que estamos chamando de id. Isso pois, caso queiramos retornar a palavra com id 2, iremos realizar uma chamada na rota &lt;code&gt;/api/Palavras/2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No exemplo acima, dizemos então que a rota recebe um atributo chamado id. Esse atributo é passado como argumento do método de nossa rota, nesse caso &lt;code&gt;int id&lt;/code&gt;. Através dessa variável, podemos realizar diversas ações específica a essa rota. No código abaixo, vemos um exemplo simples de retornar uma Palavra por id.&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Palavra&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetPalavra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;palavra&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPalavraPorId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;palavra&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status500InternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Database failure"&lt;/span&gt;&lt;span class="p"&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;h2&gt;
  
  
  Retornando Not Found
&lt;/h2&gt;

&lt;p&gt;O código acima possuí um problema. No caso de não haver uma palavra com o &lt;code&gt;id&lt;/code&gt; recebido, é retornado o código HTTP 204: No Content&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bsKhD1TI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yio7r9i3z7cfts2ce09t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bsKhD1TI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yio7r9i3z7cfts2ce09t.png" alt="Erro 204 no content"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O correto seria retornar uma mensagem de erro para o cliente, com o retorno &lt;code&gt;404 Not Found&lt;/code&gt;. Sabemos que existe um método que retorna esse erro, o &lt;code&gt;NotFoun()&lt;/code&gt;, basta então checarmos no controller se o retorno do banco está vazio ou não&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Palavra&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetPalavra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;palavra&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPalavraPorId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;palavra&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&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;palavra&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status500InternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Database failure"&lt;/span&gt;&lt;span class="p"&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;Nosso código agora, irá retornar o erro 404 caso a Palavra não seja encontrada no banco de dados, junto de um JSON que segue a RFC 7807.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://tools.ietf.org/html/rfc7231#section-6.5.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"traceId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"|6b16da39-47c24449f9eb6854."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E, como antes, no caso do método ser executado com sucesso, é retornado nosso objeto em JSON com o código HTTP 200: OK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exceptions
&lt;/h2&gt;

&lt;p&gt;Uma boa prática de quando acontecer uma exception é realizar um log dela e retornar um erro 500. Para isso, capturamos a exception e escrevemos no log. Isso pode ser feito tanto no &lt;code&gt;catch&lt;/code&gt; quanto em um &lt;a href="https://docs.microsoft.com/pt-br/aspnet/core/mvc/controllers/filters?view=aspnetcore-5.0#exception-filters"&gt;filtro que captura exceptions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O cliente então irá receber um código 500 caso ocorra algum erro interno. Se formos lançar essa exception, a aplicação irá ser suspendida, o que não seria uma boa ideia. Exceptions podem ser erros como um banco de dados indisponível, onde não temos controler por ser algo inesperado.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fontes
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/pt-br/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0#ar"&gt;https://docs.microsoft.com/pt-br/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0#ar&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.macoratti.net/19/06/aspnc_3dwebapi1.htm"&gt;http://www.macoratti.net/19/06/aspnc_3dwebapi1.htm&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.microsoft.com/pt-br/aspnet/core/mvc/controllers/filters?view=aspnetcore-5.0#exception-filters"&gt;https://docs.microsoft.com/pt-br/aspnet/core/mvc/controllers/filters?view=aspnetcore-5.0#exception-filters&lt;/a&gt;&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>aspnetcore</category>
      <category>restapi</category>
    </item>
    <item>
      <title>API Rest simples com Asp.Net Core</title>
      <dc:creator>Roberto Higor</dc:creator>
      <pubDate>Mon, 08 Mar 2021 16:43:23 +0000</pubDate>
      <link>https://dev.to/robertohigor/api-rest-simples-com-asp-net-core-5513</link>
      <guid>https://dev.to/robertohigor/api-rest-simples-com-asp-net-core-5513</guid>
      <description>&lt;h1&gt;
  
  
  API Rest simples para retornar dados
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Criando controller
&lt;/h2&gt;

&lt;p&gt;Para o controller, é criado uma classe que herda de &lt;code&gt;ControllerBase&lt;/code&gt;. Existe também a herança de &lt;code&gt;Controller&lt;/code&gt;, porém ela é utilizada somente em projetos com manipulação de páginas da Web, não para solicitações de API WEB.&lt;/p&gt;

&lt;p&gt;A classe recebe a anotação &lt;code&gt;[ApiController]&lt;/code&gt;, que fornece algumas &lt;a href="https://docs.microsoft.com/pt-br/aspnet/core/web-api/?view=aspnetcore-5.0#apicontroller-attribute"&gt;funcionalidades&lt;/a&gt; como binding sources, validações com &lt;code&gt;[Required]&lt;/code&gt;, fazendo com que seja disparado o erro 400 Bad Request automáticamente no caso de erro de validação. Além disso, &lt;a href="https://docs.microsoft.com/pt-br/aspnet/core/web-api/?view=aspnetcore-5.0#problem-details-for-error-status-codes"&gt;resultados de erro&lt;/a&gt; (código de status 400 ou superior) irão retornar uma resposta em JSON que segue a RFC 7807.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://tools.ietf.org/html/rfc7231#section-6.5.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;status:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;traceId:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0HLHLV31KRN83:00000001"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, a classe recebe uma anotação &lt;code&gt;[Route("api/[controller]")&lt;/code&gt;. O argumento &lt;code&gt;[controller]&lt;/code&gt; faz com que a rota receba o nome da classe, tirendo o sufixo Controller. Por exemplo, uma classe chamada Palavras*&lt;em&gt;Controller&lt;/em&gt;* terá, nesse caso, a rota &lt;strong&gt;api/Palavras&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Criando uma rota GET
&lt;/h2&gt;

&lt;p&gt;As rotas seguem uma estrutura de pasta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api/Palavras
    GetDefinicao   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No caso de uma classe que está recebendo a rota &lt;strong&gt;api/Palavras&lt;/strong&gt;. Caso seja criado um método, por exemplo, em uma rota customizada chamada &lt;strong&gt;GetDefinicao&lt;/strong&gt;, a URI da rota será de &lt;strong&gt;api/Palavras/GetDefinicao&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O método da rota recebe uma anotação indicando sua operação HTTP (GET, POST, PUT, PATCH, DELETE ETC). No caso de uma rota para busca de recursos, utiliza-se &lt;code&gt;[HttpGet]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Uma rota GET de recursos geralmente busca os recursos utilizando um repositório, guardando o resultado em uma variável. Em seguida, é retornado os valores para o cliente, que serão automaticamente mapeados para JSON. &lt;/p&gt;

&lt;h3&gt;
  
  
  Retornos
&lt;/h3&gt;

&lt;p&gt;No ASP.NET Core existe métodos para retornar status code, como &lt;code&gt;BadRequest()&lt;/code&gt; e &lt;code&gt;NotFound()&lt;/code&gt;. Esses métodos estão disponíveis ao definir o tipo de retorno da rota como &lt;code&gt;ActionResult&lt;/code&gt; ou &lt;code&gt;IActionResult&lt;/code&gt;. Nesse caso, utilizaremos o método para retornar Ok junto do conteúdo, que é passado como argumento. É interessante sempre retornar esses status codes, ao invés de lançar uma exceção para que o cliente receba a resposta em JSON e a aplicação não pare.&lt;/p&gt;

&lt;p&gt;Para retornar um objeto ou lista de objetos, é passado o tipo dentro de &lt;code&gt;ActionResult&lt;/code&gt;. No caso de uma lista de objetos da classe Command, é retornado .&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="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Palavra&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ou&lt;/span&gt;
&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Palavra&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A diferença entre passar um tipo para &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt; ou utilizar &lt;code&gt;IActionResult&lt;/code&gt; sem passar um tipo é a de que, no primeiro caso, será retornado automaticamente um &lt;code&gt;Ok()&lt;/code&gt; se o tipo for o mesmo do específicado, pois o retorno é convertido para &lt;code&gt;ObjectResult&lt;/code&gt;. Caso contrário, será retornado um status code de erro&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IActionResult&lt;/code&gt; é útil quando o retorno pode ser de diversos tipos.&lt;/p&gt;

&lt;p&gt;Para rotas que utilizam repositórios async, é passado a assinatura async com o retorno Task, como &lt;code&gt;Task&amp;lt;IActionResult&amp;gt;&lt;/code&gt;, lembrando de passar a assinatura &lt;strong&gt;await&lt;/strong&gt; no método assíncrono. Métodos async são úteis quando se espera uma operação externa, como por exemplo esperar o banco retornar os dados requisitados. Dessa maneira, a aplicação não é bloqueada enquanto aguarda esse retorno, podendo fazer outras requisições com outros clientes. E.g&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPalavras&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;includeTalks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Código completo&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Por ser async, é necessario await&lt;/span&gt;
        &lt;span class="c1"&gt;// Caso contrário, será retornado o OK mesmo sem atribuir o results.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;palavras&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPalavras&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;retorno&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;Results&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;palavras&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;        
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retorno&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status500InternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Database failure"&lt;/span&gt;&lt;span class="p"&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;O código acima retorna os registros no banco para o cliente. Se acontecer algum erro, é considerado como uma falha do servidor, retornando o código 500. Isso pois esse método get não recebe argumentos, como por exemplo o Id de uma entidade, que retornaria o &lt;code&gt;NotFound()&lt;/code&gt;. Por conta disso, caso ocorra algum erro, é por parte do servidor. Por não existir um método para Internal server error, é utilizado o &lt;code&gt;StatusCodes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Caso o retorno fosse ActionResult, bastaria retornar com a linha &lt;code&gt;return result;&lt;/code&gt;, que seria convertido automaticamente para um &lt;code&gt;Ok()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O método acima retorna um objeto anônimo contendo a quantidade de registros no banco e a lista com os registros. Caso queiramos uma rota que apenas retorna a lista, utilizamos do &lt;code&gt;ActonResult&amp;lt;List&amp;lt;Palvra&amp;gt;&amp;gt;&lt;/code&gt;&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;        
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Palavra&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;palavras&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPalavras&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Pelo retorno ser explícito, é retornado o Ok() automaticamente.&lt;/span&gt;
        &lt;span class="c1"&gt;// Caso o retorno não seja igual ao especificado, é retornado um erro.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;retorno&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status500InternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Database failure"&lt;/span&gt;&lt;span class="p"&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;



</description>
      <category>braziliandevs</category>
      <category>aspnetcore</category>
      <category>restapi</category>
    </item>
  </channel>
</rss>
