{"id":106,"date":"2025-01-13T00:14:00","date_gmt":"2025-01-13T00:14:00","guid":{"rendered":"https:\/\/codefornoobs.pt\/?p=106"},"modified":"2025-07-02T21:56:08","modified_gmt":"2025-07-02T21:56:08","slug":"106","status":"publish","type":"post","link":"https:\/\/codefornoobs.pt\/?p=106","title":{"rendered":"Adicionar m\u00e9todos a uma classe n\u00e3o edit\u00e1vel com Extension Methods"},"content":{"rendered":"\n<p>Extension methods s\u00e3o uma das minhas funcionalidades preferidas que o C# pode oferecer. Claro que com os anos a Microsoft tem lan\u00e7ados muitas melhorias na linguagem, mas extension methods exitem j\u00e1 ha muitos anos, desde a vers\u00e3o 3.0, e s\u00e3o muito uteis.<\/p>\n\n\n\n<p>Estes m\u00e9todos s\u00e3o uma forma de extender a funcionalidade de qualquer tipo de dados ou classe, mesmo que nativos, mas que funcionam como m\u00e9todos nativos. Para mim, uma das grandes vantagens \u00e9 mesmo a forma limpa como podemos escrever c\u00f3digo e fazer com que o c\u00f3digo fique mais f\u00e1cil de ler e de compreender.<\/p>\n\n\n\n<p>Como um exemplo simples vamos imaginar que queremos agarrar numa string e remover todos os espa\u00e7os que possam existir na string.<\/p>\n\n\n\n<p>Claro que facilmente poderia ser utilizado o m\u00e9todo replace e substituir todos espa\u00e7os por nada.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var stringComEspacos = \"teste para remover espa\u00e7os\";\r\nvar stringSemEspacos = stringComEspacos.Replace(\" \", \"\");<\/code><\/pre>\n\n\n\n<p>Assim tinhamos o problema resolvido, mas a n\u00edvel de leitura do c\u00f3digo para quem est\u00e1 a ler pela primeira vez aquele replace poder\u00e1 fazer confus\u00e3o ou at\u00e9 achar que est\u00e1 ali a faltar alguma coisa. Para evitar confus\u00e3o, poder\u00edamos criar uma fun\u00e7\u00e3o chamada RemoveSpaces e passar a string a remover os espa\u00e7os. Desta forma forma fica claro o objetivo de fazer o replace, e vamos ser sinceros, n\u00e3o interessa saber como \u00e9 que os espa\u00e7os s\u00e3o removidos, o importante \u00e9 perceber que o resultado daquela string \u00e9 a pr\u00f3pria string sem os espa\u00e7os.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public string RemoveSpaces(string stringComEspacos)\r\n{\r\n    return stringComEspacos.Replace(\" \", \"\");\r\n}<\/code><\/pre>\n\n\n\n<p>Com esta fun\u00e7\u00e3o ficar\u00edamos com o seguinte c\u00f3digo, que at\u00e9 parece bem:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var stringComEspacos = \"teste para remover espa\u00e7os\";\r\nvar stringSemEspacos = RemoveSpaces(stringComEspacos);<\/code><\/pre>\n\n\n\n<p>Agora n\u00e3o h\u00e1 confus\u00e3o sobre o que a fun\u00e7\u00e3o est\u00e1 a fazer. Ainda assim, acredito que o c\u00f3digo poderia ficar um pouco melhor e \u00e9 aqui que entra o exthension method. No fundo para tornar a nossa fun\u00e7\u00e3o removespaces num extension method basta incluir a palavra this no argumento. Um nota importante \u00e9 que o this no argumento apenas pode ser utilizado em m\u00e9todos est\u00e1ticos, portanto entre public e string tamb\u00e9m coloquei static. Abaixo deixo o m\u00e9todo completo. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public static class ExtensionMethods\n{\n    public static string RemoveSpaces(this string stringComEspacos)\n    {\n        return stringComEspacos.Replace(\" \", \"\");\n    }\n}<\/code><\/pre>\n\n\n\n<p>Com esta altera\u00e7\u00e3o o c\u00f3digo ficaria assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var stringComEspacos = \"teste para remover espa\u00e7os\";\r\nvar stringSemEspacos = stringComEspacos.RemoveSpaces();<\/code><\/pre>\n\n\n\n<p>Resumindo, com o this estamos a dizer que o \u00e9 para passar como argumento o pr\u00f3prio objecto que vem antes da chamada da fun\u00e7\u00e3o. Neste caso o stringcomescos \u00e9 passado como argumento automaticamente.<\/p>\n\n\n\n<p>Claro que aqui estamos a ver um exemplo simples, mas \u00e9 poss\u00edvel extender os m\u00e9todos para qualquer tipo de dados sejam primitivos, objectos complexos ou at\u00e9 mesmo um objecto de uma API externa. Estes m\u00e9todos n\u00e3o est\u00e3o limitados a apenas um argumento, podemos ter m\u00faltiplos argumentos, contudo apenas um pode conter o this. Os restantes argumentos s\u00e3o passados entre os par\u00eantesis da chamada da fun\u00e7\u00e3o. Um exemplo com func\u00e7\u00f5es poderia ser um m\u00e9todo para efectuar uma soma de dois n\u00fameros:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public static int Add(this int a, int b)\r\n{\r\n    return a + b;\r\n}\n\nvar cinco = 5;\nvar sete = cinco.Add(2);<\/code><\/pre>\n\n\n\n<p>Utilizo regularmente extension methods, muitas vezes para criar metodos espec\u00edficos sobre outros tipos de dados a que n\u00e3o tenho acesso \u00e0 classe para definir novos m\u00e9todos. O que costumo fazer, num projecto de maior dimens\u00e3o, \u00e9 criar uma classe para cada tipo de dados diferente. Nestes dois exemplos teria uma classe chamada StringHelper ou StringExtensionMethod e uma outra de IntHelper ou IntExtenstionMethod. Podes ainda encontrar mais informa\u00e7\u00e3o e outros exemplos diferentes diretamente na <a href=\"https:\/\/docs.microsoft.com\/pt-pt\/dotnet\/csharp\/programming-guide\/classes-and-structs\/extension-methods\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"documenta\u00e7\u00e3o da microsoft\">documenta\u00e7\u00e3o da microsoft<\/a>. Se nunca experimentaste, desafio-te a criar o teu primeiro extension method, num projeto que estejas a desenvolver.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Extension methods s\u00e3o uma das minhas funcionalidades preferidas que o C# pode oferecer. Claro que com os anos a Microsoft tem lan\u00e7ados muitas melhorias na linguagem, mas extension methods exitem j\u00e1 ha muitos anos, desde a vers\u00e3o 3.0, e s\u00e3o muito uteis. Estes m\u00e9todos s\u00e3o uma forma de extender a funcionalidade de qualquer tipo de&#8230;<\/p>\n","protected":false},"author":2,"featured_media":123,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[18,12],"tags":[7,6,9,10,8,19,21,22,20,11],"class_list":["post-106","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-features","category-melhorar-codigo","tag-net","tag-c","tag-codigo","tag-codigo-2","tag-dotnet","tag-extender-metodos","tag-extension","tag-extension-methods","tag-method","tag-programacao"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/posts\/106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=106"}],"version-history":[{"count":10,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions"}],"predecessor-version":[{"id":127,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/posts\/106\/revisions\/127"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=\/wp\/v2\/media\/123"}],"wp:attachment":[{"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codefornoobs.pt\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}