Sublinhar ou não sublinhar, eis a questão


130

Há algum problema em não prefixar os campos particulares com um sublinhado em C # se a versão binária for consumida por outras linguagens de estrutura? Por exemplo, como o C # diferencia maiúsculas de minúsculas, você pode chamar um campo "foo" e a propriedade pública "Foo" e ele funciona bem.

Isso teria algum efeito em uma linguagem que não diferencia maiúsculas de minúsculas, como o VB.NET, por problemas de conformidade com o CLS (ou outros) se os nomes forem distinguíveis apenas por maiúsculas e minúsculas?


18
O objetivo do prefixo de sublinhado, BTW, não é lidar com questões de caso. É capaz de diferenciar visual e facilmente campos e locais ao ler código. Vou usá-lo em C # e VB.
911 Neil Hewitt

2
@ NeilHewitt: Bem, isso também evita que os parâmetros de função entrem em conflito com as variáveis-membro, o que requer a adição de cada uma delas this, o que é péssimo. Edição: Acabei de responder a um comentário de quatro anos ...
Ed S.

Apenas para maior clareza o padrão oficial é _camelCase(somente leitura favorecida) github.com/dotnet/corefx/blob/master/Documentation/...
Chris Marisic

Eu prefiro _camelCase para lojas de apoio privadas. ou seja: o arquivo particular que contém os dados atribuídos e acessados ​​por meio de uma propriedade. Não gosto de propriedades automáticas porque elas não podem ser inicializadas com um valor conhecido na definição de classe e, se eu quiser um efeito colateral no setter, preciso de um repositório explicitamente declarado. Infelizmente, isso é refatorado quando uso ^ R ^ E no editor de c #, então tenho que adicioná-lo novamente ... sempre.
TomXP411

Respostas:


46

Ela terá nenhum efeito.

Parte das recomendações para a criação de bibliotecas compatíveis com CLS é NÃO ter duas entidades públicas / protegidas que diferem apenas por caso, por exemplo, você NÃO deve ter

public void foo() {...}

e

public void Foo() {...}

o que você está descrevendo não é um problema porque o item particular não está disponível para o usuário da biblioteca


1
Mesmo que não surte efeito, ainda é uma convenção com a qual eu me sentiria desconfortável - já que é uma receita para confusão se eles diferirem apenas por caso. É muito fácil ler ou digitar incorretamente se a única diferença é o capital inicial.
ChrisA

2
PS: Pessoalmente, não sublinhe em C #. Para mim é uma preferência pessoal, não uma crença religiosa
Binary Worrier

1
Eu tenho feito em ambos os sentidos e eu queria fazer a minha mente, um e para todos, com base no conhecimento: P
TheCodeJunkie

46
Estou usando sublinhados. É mais fácil distingui-los dos argumentos e variáveis ​​locais.
Rinat Abdullin

4
Eu uso _ apenas para campos particulares, no entanto, quase nunca tenho campos particulares devido à propriedade automática de 3.5. Geralmente, a única vez que tenho um campo privado é se eu implementar carregamento lento em tipos não primitivos.
Chris Marisic

278

ATUALIZAÇÃO IMPORTANTE (12 de abril de 2016):

Fomos informados de que o padrão interno da equipe do .NET CoreFX insiste em usar a notação de sublinhado sem fornecer informações sobre o porquê. No entanto, se olharmos atentamente para a regra número 3 torna-se evidente que há um sistema de _, t_, s_prefixos que sugere por que _foi escolhido em primeiro lugar.

  1. Usamos _camelCasepara campos internos e privados e usamos somente leitura sempre que possível. Prefixar campos de instância com _, campos estáticos com s_e encadear campos estáticos com t_. Quando usado em campos estáticos, readonlydeve vir depois static(ou seja, static readonlynão readonly static).
  2. Evitamos, a this.menos que seja absolutamente necessário.

Portanto, se você é como a equipe do .NET CoreFX trabalhando em algum código de desempenho, multithreaded, crítico no nível do sistema , é altamente recomendável que você:

  • aderir aos seus padrões de codificação e
  • use a notação sublinhada e
  • não leia mais esta resposta

Caso contrário, leia em ...

A RESPOSTA ORIGINAL:

Vamos primeiro concordar com o que estamos falando. A questão é como acessamos os membros da instância de métodos não estáticos e construtores de uma classe / subclasses, se modificadores de visibilidade permitirem isso.

Notação de sublinhado

  • sugere que você use o prefixo "_" nos nomes dos campos particulares
  • também diz que você nunca deve usar "isto", a menos que seja absolutamente necessário

Esta notação

  • sugere que você sempre use "isso". para acessar qualquer membro da instância

Por que essa notação existe?

Porque é assim que você

  • diferenciar um parâmetro de um campo quando eles compartilham o mesmo nome
  • verifique se você está trabalhando no contexto da instância atual

Exemplo

public class Demo
{
   private String name;
   public Demo(String name) {
       this.name = name;
   }
}

Por que existe a notação sublinhada?

Algumas pessoas não gostam de digitar "this", mas ainda precisam distinguir um campo e um parâmetro, então concordaram em usar "_" na frente de um campo

Exemplo

public class Demo
{
   private String _name;
   public Demo(String name) {
      _name = name;
   }
}

Pode-se pensar que é apenas uma questão de gosto pessoal e as duas maneiras são igualmente boas / ruins. No entanto, existem certos aspectos em que essa notação supera a notação de sublinhado:

Clareza

  • nomes de desordem de notação sublinhada
  • essa notação mantém os nomes intactos

Carga cognitiva

  • A notação de sublinhado é inconsistente, faz com que você trate os campos de uma maneira especial, mas você não pode usá-los com outros membros sempre que precisar se perguntar se precisa de uma propriedade ou de um campo.

  • esta notação é consistente, você não precisa pensar, você sempre usa "this" para se referir a qualquer membro

UPDATE: como foi apontado, o seguinte não é um ponto de vantagem

Manutenção

  • A notação sublinhada exige que você fique de olho _durante a refatoração, digamos, transformando um campo em propriedade (remover _) ou o oposto (adicionar _)

  • essa notação não tem esse problema

Preenchimento automático

Quando você precisar ver a lista de membros da instância:

  • A notação sublinhada não ajuda muito, porque quando você digita "_" o pop-up de preenchimento automático mostra os campos particulares e todos os tipos disponíveis nos assemblies vinculados misturados com o restante dos membros da instância
  • esta notação fornece uma resposta clara, digitando "this" tudo o que você vê é a lista de membros e nada mais

Ambiguidade

Às vezes, você precisa lidar com o código sem a ajuda do Intellisense. Por exemplo, quando você faz revisões de código ou navega online pelo código-fonte.

  • A notação sublinhada é ambígua: quando você vê Something.SomethingElse, não é possível dizer se algo é uma classe e SomethingElse é sua propriedade estática ... ou talvez algo é uma propriedade de instância atual que possui sua própria propriedade de SomethingElse

  • this-notation is clear: Quando você vê Something.SomethingElse, isso só pode significar uma classe com uma propriedade estática e quando você vê this.Something.SomethingElse, você sabe que Something é um membro e SomethingElse é sua propriedade

Métodos de extensão

Você não pode usar métodos de extensões na própria instância sem usar "this".

  • A notação sublinhada exige que você não use "this", mas com os métodos de extensão você deve
  • Esta notação evita que você hesite, você sempre usa "isto", ponto final.

Suporte do Visual Studio

  • notação de sublinhado não tem suporte interno no Visual Studio
  • Esta notação é suportada pelo Visual Studio naturalmente:

    1. "Este." Qualificação : prefira todos os campos não estáticos usados ​​em métodos não estáticos a serem precedidos this.em C #

Recomendações oficiais

Existem muitas diretrizes oficiais que dizem claramente "não use sublinhados", especialmente em C #


22
Esta é uma resposta incrível. Obrigado por reservar um tempo para compilar todas essas informações.
Tigran

5
Não vem do C ++, porque, no C ++, os identificadores de reserva começam com um sublinhado para o uso da linguagem e da biblioteca padrão.
Rob G

7
Por que você distingue entre código crítico de desempenho, multithread e nível de sistema e outro código? Como o uso _camelCasevai me ajudar se meu código é crítico de desempenho / código no nível do sistema?
BornToCode

6
O uso de sublinhados não tem nada a ver com escrever código crítico de desempenho, multithread ou no nível do sistema. É a consistência que importa e a equipe do CoreFX é apenas uma equipe que concordou com uma convenção específica. Esta é uma ótima resposta, apoiada por uma análise muito boa comparando convenções de nomenclatura, mas acredito que a parte adicionada dizendo "sublinhados são melhores porque a equipe do CoreFX diz isso" realmente reduz sua qualidade.
Şafak Gür

5
Meu problema é que eu entendo a inferência lógica. pt.wikipedia.org/wiki/Inference Mas, ei, entendi que não é para todos.
user603563

67

Retirado do arquivo de Ajuda do Microsoft StyleCop:

TypeName: FieldNamesMustNotBeginWithUnderscore

CheckId: SA1309

Causa: um nome de campo em C # começa com um sublinhado.

Descrição da regra:

Uma violação desta regra ocorre quando um nome de campo começa com um sublinhado.

Por padrão, o StyleCop não permite o uso de sublinhados, m_ etc. para marcar os campos de classe local, em favor do 'this'. prefixo. A vantagem de usar 'this'. é que ele se aplica igualmente a todos os tipos de elementos, incluindo métodos, propriedades, etc., e não apenas aos campos, tornando todas as chamadas para os membros da classe instantaneamente reconhecíveis, independentemente de qual editor esteja sendo usado para exibir o código. Outra vantagem é que ele cria uma diferenciação rápida e reconhecível entre membros da instância e membros estáticos, que não serão prefixados.

Se o nome do campo ou da variável tiver como objetivo corresponder ao nome de um item associado ao Win32 ou COM e, portanto, precisar começar com um sublinhado, coloque o campo ou a variável em uma classe especial NativeMethods. Uma classe NativeMethods é qualquer classe que contenha um nome que termine em NativeMethods e se destina como um espaço reservado para os invólucros Win32 ou COM. StyleCop ignorará essa violação se o item for colocado em uma classe NativeMethods.

Uma descrição de regra diferente indica que a prática preferida, além do acima, é iniciar campos particulares com letras minúsculas e públicos com letras maiúsculas.

Edit: Como acompanhamento, a página do projeto do StyleCop está localizada aqui: https://github.com/DotNetAnalyzers/StyleCopAnalyzers . A leitura do arquivo de ajuda fornece muitas informações sobre por que eles sugerem várias regras estilísticas.


7
É principalmente um tipo de coisa das "melhores práticas". Como a regra declara, o prefixo com "this" pode ser aplicado a qualquer membro não estático, enquanto o prefixo com qualquer outra coisa pode não ser aplicável devido a regras de sintaxe de idioma. A palavra-chave "this" torna o destino pretendido trivialmente claro.
21926 Scott Dorman

5
Também sou a favor da solução pretendida pela linguagem para o problema ("isso") em vez de maneiras artificiais de contorná-lo.
galaktor

10
Também existe uma regra no mesmo software que diz que você não deve ter dois campos diferentes apenas no caso. Então, o que você faz com uma variável protegida envolvida por uma propriedade pública?
Lilith River

5
Meu único problema com a coisa 'sem sublinhado' é que, ao programar em um formulário (web) ou algo assim, usar apenas 'this' não me ajuda a filtrar os campos particulares que defini e apenas me fornece uma lista gigantesca das oito milhões de outras propriedades incluídas no referido objeto.

14
O StyleCop parece estar dizendo que, se eu usar consistentemente thisao me referir a qualquer membro da classe, poderia encontrar todas as chamadas para todos os membros simplesmente procurando this. Não posso argumentar com isso, mas também não consigo pensar em um momento em que precisei fazer isso. A última coisa que quero fazer é adicionar tédio à codificação e desarrumar meu código this(que é quase húngaro) para quase nenhum ganho prático. O fato é que, se eu estou olhando para uma linha de código, qualquer coisa que comece com uma letra maiúscula ou um sublinhado é um membro da classe, qualquer letra minúscula é um local.
Devuxer

27

Como estamos falando de um campo particular, ele não afeta um usuário da sua classe.

Mas eu recomendo usar um sublinhado para o campo privado, porque ele pode facilitar a compreensão do código, por exemplo:

private int foo;
public void SetFoo(int foo)
{
  // you have to prefix the private field with "this."
  this.foo = foo;

  // imagine there's lots of code here,
  // so you can't see the method signature



  // when reading the following code, you can't be sure what foo is
  // is it a private field, or a method-argument (or a local variable)??
  if (foo == x)
  {
    ..
  }
}

Em nossa equipe, sempre usamos um prefixo de sublinhado para campos particulares. Assim, ao ler algum código, posso identificar com facilidade campos privados e diferenciá-los de locais e argumentos. De certa forma, o sublinhado pode ser visto como uma versão abreviada de "this".


14
Bem, eu sempre prefixo 'this', não importa se estou acessando um campo, propriedade ou método.
TheCodeJunkie 16/01/2009

9
Para mim, o sublinhado é uma notação abreviada de "isso".
M4N

2
Em R #, o conselho é não chamar o parâmetro foo. Por que não chamar isso de 'valor', já que você sabe que será usado para definir Foo?
thinkbeforecoding

17
@ Martin: O problema com o sublinhado como uma abreviação de "this" é que ele não pode necessariamente ser aplicado a todos os alunos enquanto "this" pode. Eu acho que o código lê muito mais fácil / mais limpo com a palavra-chave "this". No seu exemplo, o if (foo == x) sempre se refere ao parâmetro foo.
Scott Dorman

3
@TheCodeJunkie: São muitos caracteres redundantes em sua base de código.
Ed S.

15

Depois de trabalhar em um ambiente que possuía regras de estilo muito específicas e sem sentido desde então, criei meu próprio estilo. Este é um tipo que eu virei para frente e para trás muito. Eu finalmente decidi que os campos privados sempre serão _field, as variáveis ​​locais nunca terão _ e serão minúsculas, os nomes das variáveis ​​dos controles seguirão vagamente a notação húngara e os parâmetros geralmente serão camelCase.

Eu detesto a this.palavra-chave, apenas adiciona muito ruído de código na minha opinião. Adoro remover o Resharper redundante. palavra-chave

Atualização de 6 anos: eu estava analisando os internos de Dictionary<TKey,T>um uso específico de acesso simultâneo e interpretou mal um campo privado para ser uma variável local. Os campos privados definitivamente não devem ser a mesma convenção de nomenclatura que as variáveis ​​locais. Se houvesse um sublinhado, teria sido incrivelmente óbvio.


18
A thispalavra-chave é uma referência garantida ao objeto atual. Você não consegue isso com um sublinhado. Não há necessidade de detestar this.
Jason S

15
Por que inventar um 'padrão'. 'isto.' informa que o objeto é uma variável de instância 'Class'. diz que é uma variável de classe. Tudo o resto é uma variável de pilha. O sublinhado pertence à mesma pilha de más idéias em que a notação húngara agora se decompõe.
Quarkly 22/03

4
@ DRAirey1 muito fácil de perder isso. quando você precisar e você acaba fazendo coisas estranhas com o estado.
22613 Chris Marisic

3
@ ChrisMarisic É claro que você é bem-vindo à sua opinião sobre o uso _, mas não a coloque como padrão estabelecido quando claramente não é.
esmagar

3
Perdi você em "Eu criei meu próprio estilo".
Rog.ap

12

Eu gosto do sublinhado, porque então eu posso usar o nome em minúsculas como parâmetros de método como este:

public class Person
{
    string _firstName;

    public MyClass(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get { return _firstName; }
    }
}

39
public string FirstName {get; conjunto privado; }
jason

3
Você ainda pode usar as minúsculas como parâmetro do método, usando a thispalavra - chave Fazer que um ponto mute no curso e sempre controversa "para sublinhado ou não":public MyClass(string firstName){ this.firstName = firstName; }
mateuscb

5
É o futuro, agora é só public string FirstName { get; }eo setter ainda está disponível no construtor
Chris Marisic

Neste exemplo. thisseria necessário apenas no construtor. Não há necessidade de usá-lo em qualquer outro lugar. Portanto, firstNamecomo o nome do campo funciona muito bem.
Thomas Eyde

9

Eu ainda gosto muito de usar sublinhados na frente de campos particulares pelo motivo que Martin mencionou e também porque os campos particulares serão classificados no IntelliSense. Isso apesar da maldade das notações de prefixo húngaro em geral.

No entanto, nos últimos tempos, acho que usar o prefixo de sublinhado para membros privados é desaprovado, mesmo que eu não tenha muita certeza do porquê. Talvez alguém mais saiba? É apenas o princípio do prefixo? Ou havia algo envolvido com a confusão de nomes de tipos genéricos que recebem sublinhados neles em assemblies compilados ou algo assim?


4
Para mim, as _ desordenam as palavras quando rapidamente vasculham o código, torna-se menos como apenas ler _ e _ mais como ter que parar em _todo _ para reconhecê-lo e perceber que não é um caractere de controle de algum tipo. Ele também interrompe o recuo pressionando praticamente o primeiro caractere útil nos nomes de campo uma coluna para a direita. Eu geralmente não gostam de C ++ porque a maioria C ++ - os programadores tendem a escrever incrivelmente concisa e slow-to-read símbolo / máquina-como código e eu simplesmente preferem não ter isso em C # código :)
Oskar Duveborn

23
Para mim, isso. desordenar as palavras.este quando, rapidamente, isto. varrendo o código, torna-se menos como apenas ler isso. e isso. mais isso. como ter que parar e isso. para reconhecê-lo e isso. perceber que é isso. não é um caractere de controle de alguns. Eu preferiria encontrar o ocasional _fieldFooou _fieldBara ter meu uso desordenado com this.fieldFooor this.fieldBar. Acho o this.prefixo muito mais dissonante do que um sublinhado líder.
AggieEric

Eu estava pensando que talvez essa discrepância na experiência possa resultar de sistemas de arquivos antigos ou protocolos de transferência de arquivos em que não eram permitidos espaços, os quais treinavam alguns usuários a ver os sublinhados como espaços e, portanto, não distrair a leitura. Eu, por outro lado, têm problemas com tais nomes de arquivos como eu sempre utilizado espaços em meus próprios nomes desde o início ...
Oskar Duveborn

1
@AggieEric acertou a unha na cabeça lá. Só de ler sua frase me dá dor de cabeça! Tentei seguir a recomendação da EM há anos nesse assunto e fiquei tão cansado de ler pequenas thispalavras azuis em todos os lugares que tomei uma decisão de raiva nerd ali. Agora, uso religiosamente apenas thispara referências de propriedades ou quando preciso distinguir explicitamente entre thise base. Cada um na sua, eu acho :-)
Riegardt Steyn

1
Eu acho que é porque, finalmente, iniciar qualquer coisa com um caractere de pontuação prejudica a legibilidade. Parece não incomodar a todos, mas para mim parece muito pouco natural ler qualquer coisa que comece com pontuação. Quanto mais o código for em inglês, mais fácil será a leitura. E com os IDEs modernos, é muito simples dizer a diferença entre locais e membros privados, porque provavelmente serão de cores diferentes.
Tim Long

5

Recomenda-se Style Cop ou não, cavar no .NET Framework mostra muito uso de "_" para variáveis ​​de membro. O que os criadores do Style Cop recomendam, não é o que a maioria dos funcionários da MS está usando. :) Então, eu vou ficar com o sublinhado. Porque eu pessoalmente cometi muito menos erros usando o sublinhado do que este (exemplo: usando varName = varName em vez de this.varName = varName, está realmente preso em mim)


3
Também é recomendado sublinhado para o guia .NET estilo core: github.com/dotnet/corefx/wiki/Coding-style
landoncz

3

Penso que, em geral, os campos em nível de classe são um erro no design da linguagem. Eu teria preferido se as propriedades do C # tivessem seu próprio escopo local:

public int Foo
{
   private int foo;
   get
   {
      return foo;
   }
   set
   {
      foo = value;
   }
}

Isso tornaria possível parar completamente de usar campos.

A única vez que prefixo um campo privado com sublinhado é quando uma propriedade requer um campo de apoio separado. Essa também é a única vez que uso campos particulares. (E como nunca uso campos protegidos, internos ou públicos, é a única vez que uso o período dos campos.) No que me diz respeito, se uma variável precisa ter escopo de classe, é uma propriedade da classe.


A turma do C # parece concordar com você com o novato private int foo {get; set;} sintaxe açúcar.
Dana

Ah com certeza; o que estou descrevendo aqui é totalmente impraticável sem isso.
Robert Rossney

O que você está descrevendo é "Propriedades implementadas automaticamente". Infelizmente, com o Visual Basic.NET, isso realmente usa uma variável _prefix "oculta" nos bastidores, ou seja, se você tivesse uma propriedade autoimplementada "Propriedade pública Foo como número inteiro", NÃO poderia ter a declaração da variável membro "Private _foo as Inteiro "

Não, não estou descrevendo propriedades implementadas automaticamente, pelo menos não no meu exemplo. Estou descrevendo um nível de escopo que não existe em C # ou VB. É realmente lamentável que o VB tenha escolhido uma maneira tão trivial de alterar os nomes dos campos de apoio. C # é feio o suficiente para que você nunca crie uma variável com o mesmo nome por acidente.
Robert Rossney

3

A notação _fieldName para campos particulares é tão fácil de quebrar . Usando "isso". é impossível quebrar a notação. Como você quebraria a notação _? Observar:

private void MyMethod()
{
  int _myInt = 1; 
  return; 
}

Pronto, eu acabei de violar sua convenção de nomenclatura, mas ela é compilada. Eu preferiria ter uma convenção de nomenclatura que não seja húngara eb) explícita. Sou a favor de acabar com a nomeação húngara e isso se qualifica de certa forma. Em vez do tipo de um objeto na frente do nome da variável, você tem seu nível de acesso.

Compare isso com Ruby, onde o nome da variável @my_numbervincula o nome ao escopo e é inquebrável.

edit: Esta resposta foi negativa. Eu não ligo, fica.


11
Não é uma crítica válida de uma convenção de nomenclatura dizer que é possível que os desenvolvedores não a sigam.
Robert Rossney

8
Uau, sua definição de “fácil de quebrar” e a minha são como opostos completos. O seu significa "fácil de quebrar intencionalmente", enquanto a maioria das outras pessoas provavelmente significa "fácil de quebrar acidentalmente ". Vou deixar isso como um exercício para o leitor a descobrir qual deles é mais relevante em escrever código legível ...
Konrad Rudolph

6
@ Konrad: Você parece pretensioso quando diz "como um exercício para o leitor". Este não é um livro de matemática.
jcollum

3
Um pouco menos negativo agora :) Embora possamos remar contra a corrente, também não gosto da convenção de sublinhado. Na minha opinião, não é diferente da notação húngara e, para ser sincero, faz meus olhos sangrarem (prejudica a legibilidade). Lançamos a notação húngara com C # e é hora de eliminar esse último vestígio de não confiar em seu IDE.
Tim Long

1
Ouvi dizer que a Microsoft realmente diz que o sublinhado não deve ser usado em seu guia de estilo C #. blogs.msdn.microsoft.com/brada/2005/01/26/… - seção 2.6 - parece que Brad Abrams concorda pelo menos com a gente!
Jcollum

1

Quando você deseja que seu assembly seja compatível com CLS, você pode usar o atributo CLSCompliant em seu arquivo assemblyinfo. O compilador irá reclamar quando seu código contiver itens que não são compatíveis com cls.

Então, quando você tiver duas propriedades que diferem apenas no caso, o compilador emitirá um erro. Por outro lado, quando você possui um campo privado e uma propriedade pública na mesma classe, não haverá problemas.

(Mas também prefixo sempre meus membros privados com um sublinhado. Isso também me ajuda a deixar claro quando leio meu código que uma determinada variável é um campo de membro).


0

Eu gosto de usar sublinhados na frente dos meus campos particulares por dois motivos. Um já foi mencionado, os campos se destacam de suas propriedades associadas no código e no Intellisense. A segunda razão é que eu posso usar as mesmas convenções de nomenclatura, seja codificando em VB ou C #.


1
whoah, isso é sábio? Não sublinhado significa 'continua na próxima linha' no VB?
precisa saber é o seguinte

1
Somente se o sublinhado for seguido por um espaço.
Rob Windsor

Letra inicial de ser minúscula ou maiúscula destacam-se muito bem para mim :)
ManoDestra

0

Não há implicações. Quando seu código é compilado, tudo o que é importante para o compilador é o namespace e a visibilidade do campo / propriedade. Um sublinhado é tão significativo quanto qualquer outro caractere ao nomear um identificador. O verdadeiro truque é usar uma convenção que você e as pessoas ao seu redor entenderão.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.