Você deve usar privado em campos e métodos em c #?

8

Eu sou um pouco novo em C # e acabei de descobrir que: em C # todos os campos e métodos em uma classe são privados por padrão. Significando que isso:

class MyClass
{

string myString

}

é o mesmo que:

class MyClass
{

private string myString

}

Então, como são iguais, devo usar a palavra-chave private em campos e métodos? Muitos exemplos de código online usam a palavra-chave private em seu código, por que isso?

user3210251
fonte
34
Bem, para iniciantes, torna óbvio que você pretendia tornar seu campo privado, em vez de apenas esquecer de incluir um especificador de escopo.
KChaloux
4
Estou desconfortável por não usar private. Isso gera menos dissonância cognitiva para mim, se eu sempre posso esperar ver o especificador de escopo como a primeira parte de uma declaração de identificador. Leva-me menos tempo para ler "privado" do que para descobrir que a primeira palavra não é um especificador de escopo e, sim, isso significa que é uma declaração de membro particular. Escrever código também significa ter que lê-lo mais tarde.
Robert Harvey
3
@RobertHarvey Também pode ser completamente subjetivo; ao codificar em C ++, sempre omiti tudo o que era opcional, porque senti que isso me distraía, até que percebi que outras pessoas que estavam lendo meu código podem estar acostumadas a convenções de codificação mais detalhadas. Portanto, é uma questão de gosto (em um projeto pessoal) e convenção (ao colaborar).
Marczellm
2
@gnat Não tenho certeza se isso é uma duplicata dessa pergunta. Tem certeza de que postou o link certo?
Maple_shaft
4
@gnat É muito difícil perguntar por que alguém declararia explicitamente que a palavra-chave privada em seu código é uma pergunta sobre o estilo de codificação. Esta questão é muito mais específica do que isso. Eu sinto que, embora uma resposta canônica possa cobrir uma pergunta diferente, uma pergunta mais específica às vezes pode merecer sua própria resposta.
Maple_shaft

Respostas:

38

Só porque você pode omitir feeds de linha e recuos e seu compilador C # ainda entenderá o que você quer dizer, não é automaticamente uma boa ideia fazer isso.

using System; namespace HelloWorld{class 
Hello{static void Main(){Console.WriteLine
("Hello World!");}}}

é muito menos legível para o leitor humano do que:

using System;
namespace HelloWorld
{
    class Hello 
    {
        static void Main() 
        {
            Console.WriteLine("Hello World!");
        }
    }
}

E esse é o ponto aqui: os programas são escritos para dois públicos:

  • O compilador ou intérprete.
  • Você e outros programadores.

O último é aquele que precisa entender e compreender rapidamente o significado do que está escrito. Por esse motivo, existem algumas boas práticas que surgiram ao longo dos anos e são quase ou quase-padrões geralmente aceitos. Uma delas é colocar palavras-chave de escopo explícitas, outro exemplo é colocar parênteses extras em torno de expressões complexas, mesmo nos casos em que elas não seriam necessárias sintaticamente, como:

(2 + 5) & 4
JensG
fonte
2
+1 Em particular para esse último ponto. Embora estritamente falando, os programadores devam saber a ordem das operações para seu idioma, sempre tento adicionar parênteses extras sempre que possível, porque no passado eu estava perdendo alguns segundos tentando pensar em qual operação ocorre primeiro e se uma expressão avalia ou não a expressão. do jeito que eu acho que faz. Ocasionalmente, a resposta é "Não, eu entendi errado" e essas ocasiões podem ser evitadas com o uso razoável de colchetes, principalmente quando você considera casos como o 5 + 5 * 5são 30, não 50como alguns podem esperar à primeira vista.
Pharap
1
+1. Há um ligeiro soluço mental para mim quando não vejo modificadores explícitos de visibilidade. Eu tenho que pensar por uma fração de segundo: "O padrão é público ou privado?" simplesmente porque eu sempre uso os modificadores e, quando alguém não usa, isso me impressiona.
precisa saber é o seguinte
6
Você quer dizer **private** static void Main()? :)
Jesse C. Slicer
6

C # não é a única linguagem de programação para .NET; outros idiomas podem e têm acessibilidade padrão diferente em vários contextos. A especificação privatedeixará claro para quem ler o código que essa acessibilidade é pretendida, enquanto a omissão da especificação deixa em aberto a questão de saber se o membro pode ter sido, por exemplo, destinado a ser usado dentro do assembly [como seria o padrão no VB.NET] . Ser explícito pode ser especialmente útil se você usar vários idiomas com regras diferentes.

Com relação a se deve privateou protectednão ser favorecido na ausência de um argumento particularmente convincente a favor do outro, a decisão deve se basear em se é mais provável que a exposição de um membro torne possível a uma classe derivada fazer algo útil que caso contrário, não seria possível ou impediria que versões futuras de uma classe modificassem suas estruturas de dados internas de uma maneira que fosse mais eficiente. Pode-se ver exemplos de ambas as situações em List<T>.

Em alguns casos, se houver uma lista de agregados (por exemplo, Pointestruturas), pode ser útil atualizar itens no local. Se List<T>exposto seu armazenamento de suporte a classes derivadas, pode-se definir facilmente um EditableList<T>com um método:

delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2);

void ActOnItem<TParam>(int index, ref TParam param, ActByRef<TParam> proc)
{
  .. test index, then...
  proc(ref _arr[index], ref proc);
}

que poderia então ser chamado usando algo como:

int adjustmentAmount = ...;
myList.ActOnItem(index, ref adjustmentAmount, 
  (ref Point pt, ref int dx) => pt.X += dx );

Esse método pode permitir atualizações eficientes, mesmo com tipos de estrutura relativamente grandes [já que nenhuma cópia seria necessária]. O fato de List<T>não expor seus componentes internos torna impossível derivar uma classe que poderia implementar esse operador com eficiência.

Por outro lado, embora, até onde eu saiba, a Microsoft ainda não tenha explorado essa capacidade, ter o armazenamento secundário privado tornaria possível para uma versão futura List<T>dividir o armazenamento secundário em partes menores que 85K ao usar a maioria dos dados. tipos ou menores que 1000 itens ao usar double. Essa divisão não seria possível se List<T>houvesse exposto o armazenamento de suporte a classes derivadas.

supercat
fonte
Como os campos são padrão privado Eu não espero Intermediate Common Language saída do C # compilador de int myFielde private int myFieldpara ser diferente. Portanto, não acredito que a adição de privado deixe aberta a interpretação para outras linguagens .NET.
Roy T.
@RoyT .: Meu argumento foi que, se vários idiomas estão em uso, pode não estar claro que um membro com um especificador de acesso omitido deveria ter o acesso que seria o padrão em um idioma diferente.
Supercat
ah eu entendo agora. Você estava se referindo tão explicitamente a outras linguagens .NET que eu entendi como programas que não entendem, não pessoas.
Roy T.
1
@RoyT .: Editei o primeiro parágrafo; isso torna mais claro?
Supercat 5/14
2

Sim, você deve usá-lo private:) A palavra-chave é usada porque geralmente é uma prática aceita e remove todas as dúvidas sobre o escopo pretendido de um aluno.

A legibilidade é muito importante com o código, especialmente quando se trabalha em equipe. Se você quiser examinar melhor a legibilidade do código, um bom livro de referência que posso recomendar é The Elements of C # Style .

ocasionalDev
fonte
-4

Questão:

"Você deve usar privado em campos e métodos em C #?"

Resposta rápida:

Sim, mas isso depende da sua lógica de código.

Resposta estendida longa e chata:

Sugiro, sempre especifique a vissibilidade dos membros.

Eu acho que é uma boa abordagem declarar membros, por padrão, como "particulares".

No mundo real, eu uso "protegido".

Mais cedo ou mais tarde, esse membro oculto pode ser usado por uma subclasse.

Às vezes, uma boa pergunta pode ser melhor respondida, fazendo a pergunta oposta.

A pergunta oposta, à sua pergunta, pode ser algo como:

"Devo usar sempre modificador de acesso público em campos e métodos em C #"

Em outras linguagens de programação, você pode "promover" protegido ao público, dependendo do seu design.

Eu uso muitas bibliotecas de hierarquia profunda de controle (visual), onde alguns membros (propriedades, methos) são necessários.

Às vezes, é melhor tê-los em público, às vezes não.

umlcat
fonte
5
Usar o protegido como seu especificador pode ser ruim. Ele potencialmente abre a superclasse para manipulação que pode não ser apropriada, pois uma subclasse pode ser capaz de solucionar verificações de erro ou restrições impostas na superclasse. Mesmo que não seja esse o caso, ele ainda polui as subclasses com variáveis ​​adicionais no escopo que são redundantes (por exemplo, a variável protegida com um acessador agora oferece duas maneiras de alterá-lo em uma subclasse).
2
-1: Não tenta resolver a questão.
mattnz
1
Público e protegido são IMHO mais próximos do que privados e protegidos. Eles fazem parte da interface da classe. Membros privados são apenas estado interno da caixa preta.
Petter Nordlander
+1 porque gosto de declarar privado, mesmo que não seja necessário. Um bom código tem muito a ver com legibilidade e funcionalidade.
precisa saber é o seguinte
2
-1 Usar protegido como padrão é um péssimo conselho. Você sempre pode aumentar a visibilidade dos membros posteriormente, mas não o contrário, sem quebrar o código (quando as pessoas estão usando o seu código).
Oliver Weiler