Ordem dos itens nas classes: Campos, Propriedades, Construtores, Métodos

637

Existe uma diretriz oficial em C # para a ordem dos itens em termos de estrutura de classe?

Vai:

  • Campos públicos
  • Campos Privados
  • Propriedades
  • Construtores
  • Métodos
    ?

Estou curioso para saber se existe uma regra rígida e rápida sobre a ordem dos itens? Estou meio que em todo lugar. Quero seguir um padrão específico para poder fazer isso em qualquer lugar.

O verdadeiro problema é que minhas propriedades mais complexas acabam parecendo muito com métodos e elas parecem deslocadas no topo antes do construtor.

Alguma dica / sugestão?

mmcdole
fonte
7
Na verdade, para responder à pergunta real, não, não há orientação oficial. O StyleCop implementa as diretrizes desenvolvidas para uso em um grupo específico da Microsoft. Esta não é uma diretriz oficial e pode até não ser uniforme entre os grupos da Microsoft.
31413 John Saunders
2
Um truque fácil é ver os metadados de alguma classe complexa no .net (F12 no VS). Você saberá como é ordenado pelo menos para os membros publice protected.
Nawfal # 20/13
19
Esta pergunta não é baseada em opiniões, pois pergunta se há uma diretriz oficial. Ou há uma diretriz ou não!
Simon MᶜKenzie
2
@awawfal Sei que este é um comentário antigo, eu gosto do truque que você mencionou, mas vale a pena mencionar que ele não será exibido privateou os internalmembros (acredito). Ótima maneira de ver publice protected, no entanto. Podemos ver a fonte das classes do .NET Framework, aqui também referênciasource.microsoft.com
Adam Plocher

Respostas:

950

De acordo com a documentação das regras da StyleCop, o pedido é o seguinte.

Dentro de uma classe, estrutura ou interface: (SA1201 e SA1203)

  • Campos Constantes
  • Campos
  • Construtores
  • Finalizadores (Destrutores)
  • Delegados
  • Eventos
  • Enums
  • Interfaces ( implementações de interface )
  • Propriedades
  • Indexadores
  • Métodos
  • Estruturas
  • Aulas

Em cada um desses grupos, faça o pedido por acesso: (SA1202)

  • público
  • interno
  • interno protegido
  • protegido
  • privado

Dentro de cada um dos grupos de acesso, ordene por estático e depois não estático: (SA1204)

  • estático
  • não estático

Dentro de cada um dos grupos de campos estáticos / não estáticos, ordene somente leitura e depois não somente leitura: (SA1214 e SA1215)

  • somente leitura
  • não readonly

Uma lista não enrolada tem 130 linhas, então não a desenrolarei aqui. A parte dos métodos desenrolada é:

  • métodos estáticos públicos
  • métodos públicos
  • métodos estáticos internos
  • métodos internos
  • métodos estáticos internos protegidos
  • métodos internos protegidos
  • métodos estáticos protegidos
  • métodos protegidos
  • métodos estáticos privados
  • métodos privados

A documentação observa que, se a ordem prescrita não for adequada - por exemplo, várias interfaces estão sendo implementadas e os métodos e propriedades da interface devem ser agrupados -, use uma classe parcial para agrupar os métodos e propriedades relacionados.

Jonathan Wright
fonte
31
Eu gostaria de agradecer por você ter se esforçado neste post. Estou tentando tornar o StyleCop um padrão (mesmo que seja apenas consistente e facilite a localização de coisas) e isso é valioso.
22909 Kenny Mann
47
Pessoalmente, acho a ordenação de métodos estáticos irritante. Eu posso ver o argumento para métodos públicos estáticos chegando primeiro, mas normalmente quero métodos estáticos privados após os membros. Eles são utilitários, afinal.
23909 Jonathan Wright
18
Eu gostei da ponta classe parcial
Keith Sirmons
10
Apenas uma nota sobre classes parciais. Dado que, durante o tempo de compilação, todas as parciais são compiladas em um único tipo, eu sempre tentava garantir um bom motivo para criar essa sobrecarga adicional. O principal motivo para as classes parciais é estender o código-fonte de geração automática ou ao trabalhar em grandes projetos para permitir que vários desenvolvedores trabalhem na mesma classe, mas separam arquivos.
Nope
4
@ FrançoisWahl A sobrecarga associada ao compilador combina classes parciais em um único tipo desse tamanho?
dav_i 4/09/12
38

Em vez de agrupar por visibilidade ou por tipo de item (campo, propriedade, método etc.), que tal agrupar por funcionalidade?

Ryan Lundy
fonte
3
Se "classificar" usando as recomendações do StyleCop, é um tipo de funcionalidade. Há uma boa razão pela qual alguns métodos são públicos e outros são privados. O código é realmente melhor legível: Se abrir cs uma classe File I ver imediatamente os métodos públicos que são "mais importante" do que as privadas (para o cara que está usando essa classe)
hfrmobile
75
Se você tem tantos métodos, propriedades etc. em sua classe que precisa agrupá-los por seção, talvez seja um sinal de que a classe está fazendo muito?
Ryan Lundy
10
Mesmo que a classe seja pequena, não faria sentido agrupar métodos públicos com seus métodos privados correspondentes, que são chamados apenas por esse método público?
Markus Meyer
11
+1 se o método público Foo () chamar InternalFoo () protegido / privado (), é melhor que o segundo método esteja logo abaixo de DoFoo () na fonte, não em algum lugar mais abaixo entre outros métodos protegidos / privados.
precisa saber é o seguinte
60
agrupamento por funcionalidade é chamada de uma classe
MrDosu
26

Esta é uma pergunta antiga, mas ainda muito relevante, então acrescentarei o seguinte: Qual é a primeira coisa que você procura quando abre um arquivo de classe que pode ou não ter lido antes? Campos? Propriedades? Percebi por experiência que quase invariavelmente vou caçar os construtores, porque a coisa mais básica a entender é como esse objeto é construído.

Portanto, comecei a colocar os construtores em primeiro lugar nos arquivos de classe e o resultado foi psicologicamente muito positivo. A recomendação padrão de colocar os construtores atrás de várias outras coisas parece dissonante.

O próximo recurso de construtor primário no C # 6 fornece evidência de que o local natural para um construtor está no topo de uma classe - na verdade, os construtores primários são especificados mesmo antes da chave aberta.

É engraçado quanta diferença uma reordenação como essa faz. Isso me lembra de como as usinginstruções costumavam ser ordenadas - primeiro com os namespaces do sistema. O comando "Organizar usos" do Visual Studio usou esse pedido. Agora, os usings são apenas ordenados alfabeticamente, sem tratamento especial dado aos namespaces do sistema. O resultado parece mais simples e limpo.

brilhante
fonte
2
Inicialização / construção de classe é, na minha opinião, complicada. Os campos são inicializados antes que os construtores explícitos sejam executados; portanto, seguindo seu argumento de essencialmente colocar membros na ordem em que são usados ​​/ criados, os campos inicializados seriam antes dos construtores declarados explicitamente. Campos estáticos inicializados e construtores estáticos o tornam ainda mais interessante.
David Culp
1
Na verdade, a ordem em que eles tendem a ser procurados pelos seres humanos, a noção de programação literária de que o código deve primeiro ser legível pelos seres humanos.
brilhante
1
Note que construtores primários foram removidos dos planos para C # 6: stackoverflow.com/a/26915809/5085211
Fuglede
4
Nove em cada dez vezes, procuro a interface pública, e é por isso que coloco todos os membros públicos em primeiro lugar, seguidos por internos, seguidos por protegidos e finalmente por privados.
Matt Davis
15

Não conheço um idioma ou padrão do setor, mas costumo colocar as coisas nessa ordem com cada seção agrupada em uma # região:

usando instruções

Namespace

Classe

Membros privados

Propriedades públicas

Construtores

Métodos públicos

Métodos particulares

Wayne
fonte
É exatamente assim que eu faço. Exceto entre classe e membros privados, não tenho qualquer constantes públicas e Enums etc.
deegee
Sim, prefiro manter propriedades públicas após métodos particulares. Outras pessoas preferem colocar o construtor antes das propriedades públicas ... mas, na minha cabeça, prefiro ter valores / construtores / comportamentos, nessa ordem. Então "valores" é dividido como constantes / privateMembers / properties e assim. Normalmente, não uso regiões, exceto alguns modelos de visualização grandes ... bem, os modelos de exibição do WPF são meio especiais e, nesse caso, geralmente coloco os campos privados de apoio imediatamente antes de cada propriedade pública. Neste caso, o conjunto de campo privado mais o membro do público é a mesma unidade
zameb
15

Eu recomendaria usar os padrões de codificação da IDesign ou os listados no site de Brad Abram . Esses são os dois melhores que eu encontrei.

Brad diria ...

O membro das classes deve estar em ordem alfabética e agrupado em seções (Campos, Construtores, Propriedades, Eventos, Métodos, Implementações de Interface Privada, Tipos Aninhados)

Elijah Manor
fonte
3
Esse link parece levar apenas à home page da IDesign atualmente. Parece que os padrões de codificação estão escondidos atrás de um link de download Emailed estes dias #justsaying
Liam
As diretrizes devem ter justificativa. A lógica para isso é: 1. para que você entenda, 2. para que você possa aplicar julgamento em casos limítrofes, sutis, ambíguos, imprevistos ou conflitantes, 3. para que você possa ajustar quando as condições mudarem e algumas diretrizes não se aplicarem mais.
Pablo H
6

Como mencionado anteriormente, não há nada na linguagem C # que dite o layout, eu pessoalmente uso regiões e faço algo assim para uma classe média.

public class myClass
{
#region Private Members

#endregion
#region Public Properties

#endregion

#region Constructors

#endregion
#region Public Methods

#endregion
}

Faz sentido para mim de qualquer maneira

Mitchel Sellers
fonte
19
Aqui está o seguinte (apenas para informação) que o stylecop não recomenda o uso de regiões (SA1124 DoNotUseRegions)
Gerwald
1
@zwcloud Claro, em um arquivo com 5538 linhas, as regiões são necessárias, mas isso não significa que você deve usar regiões em arquivos normais.
Ghost4Man 27/05
1
@ Gerwald: Eu acho que o StyleCop é apenas para pessoas que usam o StyleCop. É um dos muitos padrões
zameb
1
@ zameb: Eu diria que as regras do StyleCop são uma das diretrizes de codificação mais comuns para C #. Ao codificar em qualquer idioma, estou sempre tentando encontrar o conjunto mais comum de diretrizes de codificação e segui-las.
Gerwald
5

De StyleCop

campos privados, campos públicos, construtores, propriedades, métodos públicos, métodos privados

Como o StyleCop faz parte do processo de criação da MS, você pode vê-lo como um padrão de fato

blowdart
fonte
Interessante. Você usa o StyleCop regularmente?
mmcdole 29/09/08
Para um projeto, sim, porque ele é usado para alguns trabalhos de contrato da MS de vez em quando. É um sorriso
blowdart 29/09/08
1
O uso do StyleCop por um longo período de tempo e o uso dessas recomendações tornam o código realmente mais legível: Se você abrir o arquivo .cs de uma classe, vejo imediatamente os métodos públicos que são "mais importantes" que os particulares. Os públicos são os "interfaces" da classe que ele oferece eo que pode ser testado (preferem TDD, e Test-First)
hfrmobile
1
De acordo com campos públicos StyleCop deve ir antes campos privados stylecop.com/docs/SA1202.html
Michael Freidgeim
1
O que você quer dizer com "StyleCop faz parte do processo de criação do MS"? A Microsoft está usando o StyleCop para todo o seu código?
Rico Suter
5

Normalmente, tento seguir o próximo padrão:

  • membros estáticos (geralmente têm outro contexto, devem ser seguros para threads, etc.)
  • membros da instância

Cada parte (estática e instância) consiste nos seguintes tipos de membros:

  • operadores (sempre estáticos)
  • campos (inicializados antes dos construtores)
  • construtores
  • destruidor ( é uma tradição seguir os construtores )
  • propriedades
  • métodos
  • eventos

Em seguida, os membros são classificados por visibilidade (de menos para mais visível):

  • privado
  • interno
  • protegido interno
  • protegido
  • público

A ordem não é um dogma: classes simples são mais fáceis de ler, no entanto, classes mais complexas precisam de agrupamentos específicos ao contexto.

Michael Damatov
fonte
5

Minha preferência é ordenar por tipo e depois diminuir a visibilidade da seguinte forma

public methods
public events
public properties

protected methods
protected events
protected properties

private methods
private events
private properties
private fields

public delegates
public interfaces
public classes
public structs

protected delegates
protected interfaces
protected classes
protected structs

private delegates
private interfaces
private classes
private structs

Sei que isso viola o Style Cop e, se alguém puder me dar uma boa razão para colocar os detalhes de implementação de um tipo antes de sua interface, estou disposto a mudar. Atualmente, tenho uma forte preferência por colocar os membros em último lugar.

Nota: Não uso campos públicos ou protegidos.

Aluan Haddad
fonte
3
Acordado. Eu realmente me pergunto se a noção de colocar os membros privados em primeiro lugar não é uma ressaca dos dias C em que as variáveis ​​tiveram que ser declaradas primeiro. Eu quase sempre quero ver a interface pública primeiro, não os internos da classe.
Matt Davis
1
Isso realmente faz muito sentido. Aposto que é um resquício de C.
Aluan Haddad
Algumas das maiores pegadinhas podem ser as propriedades IMO. Quando existe uma lógica em um getter / setter que você desconhecia, será muito mais provável que ocorra efeitos colaterais em métodos (nos quais você naturalmente espera que eles estejam). Portanto, prefiro propriedades ao lado de seus campos no topo , então, quando estou vendo uma aula pela primeira vez, vejo a pegadinha lá em cima. Onde como quando leio um método, eu normalmente navegar / saltar imediatamente para o método de qualquer maneira
Ryan A Leach
4

O mais próximo que você provavelmente encontrará é "Diretrizes de design, código gerenciado e o .NET Framework" ( http://blogs.msdn.com/brada/articles/361363.aspx ) por Brad Abrams

Muitos padrões são descritos aqui. A seção relevante é 2.8, eu acho.

Rory Becker
fonte
3

as únicas diretrizes de codificação que vi sugeridas para isso são colocar os campos na parte superior da definição da classe.

Eu costumo colocar os construtores a seguir.

meu comentário geral seria que você deveria manter uma classe por arquivo e, se a classe for grande o suficiente para que a organização das propriedades versus métodos seja uma grande preocupação, qual é o tamanho da classe e você deve refatorá-la de qualquer maneira? representa várias preocupações?

Hamish Smith
fonte
3
e depois de precisar de regiões ... você perdeu.
21912 Hamish Smith
3

Eu prefiro colocar os campos privados no topo junto com o (s) construtor (es), depois colocar os bits da interface pública depois disso, depois os bits da interface privada.

Além disso, se a definição de sua classe for longa o suficiente para que a ordem dos itens seja importante, provavelmente é um cheiro de código indicando que sua classe é muito volumosa e complexa e você deve refatorar.

Cunha
fonte
3

Eu mantenho o mais simples possível (pelo menos para mim)

Enumerações
Declarações
Construtores
Substitui
Métodos
Propriedades
Manipulador de Eventos

Pat
fonte
2

Certamente não há nada na linguagem que a imponha de maneira alguma. Costumo agrupar as coisas por visibilidade (pública, depois protegida e depois privada) e usar #regions para agrupar as coisas relacionadas funcionalmente, independentemente de ser uma propriedade, método ou qualquer outra coisa. Os métodos de construção (sejam os reais ou as funções estáticas da fábrica) geralmente estão no topo, pois são a primeira coisa que os clientes precisam saber.

Jeff Kotula
fonte
Também uso regiões para separar a visibilidade, e ter um layout de código regional para me manter honesto. rauchy.net/regionerate
Ponto e vírgula esquecido
Não vejo problema em usar #regions, no entanto, muitas vezes acho que, assim que sou tentado a entrar em uma região, isso me leva a pensar em dividir minhas aulas.
Mikecamimo
2

Sei que isso é antigo, mas meu pedido é o seguinte:

em ordem pública, protegida, privada, interna, abstrata

  • Constantes
  • Variáveis ​​estáticas
  • Campos
  • Eventos
  • Construtor (es)
  • Métodos
  • Propriedades
  • Delegados

Também gosto de escrever propriedades como esta (em vez da abordagem abreviada)

// Some where in the fields section
private int someVariable;

// I also refrain from
// declaring variables outside of the constructor

// and some where in the properties section I do
public int SomeVariable
{
    get { return someVariable; }
    set { someVariable = value; }
}

fonte