Pergunta

Eu vejo um monte de exemplo de código para classes C # que faz isso:

public class Point {
    public int x { get; set; }
    public int y { get; set; }
}

Ou, no código antigo, o mesmo com um valor de apoio privado explícita e sem as novas propriedades implicam programas de auto:

public class Point {
    private int _x;
    private int _y;

    public int x {
        get { return _x; }
        set { _x = value; }
    }

    public int y {
        get { return _y; }
        set { _y = value; }
    }
}

A minha pergunta é o porquê. Existe alguma diferença funcional entre fazer o exposto, e apenas fazendo esses membros campos públicos, como abaixo?

public class Point {
    public int x;
    public int y;
}

Para ser claro, eu entendo o valor de getters e setters quando você precisa fazer alguma tradução dos dados subjacentes. Mas nos casos em que você está apenas passando os valores através, parece desnecessariamente verbose.

Foi útil?

Solução

Eu tendo a concordar (que parece desnecessariamente verbose), embora este tenha sido um problema a nossa equipe ainda não resolvido e para que os nossos padrões de codificação ainda insistem em verboso propriedades para todas as classes.

Jeff Atwood lidado com isso há alguns anos. O ponto mais importante que ele retrospectivamente observado é que a mudança de um campo a uma propriedade é um alteração significativa em seu código; qualquer coisa que consome deve ser recompilados para trabalhar com a nova interface de classe, por isso, se qualquer coisa fora de seu controle está consumindo sua classe que você pode ter problemas.

Outras dicas

Também é muito mais simples para mudá-lo a isso mais tarde:

public int x { get; private set; }

Ele encapsula a definição e acesso desses membros. Se algum tempo a partir de agora um desenvolvedor para as necessidades de código a lógica mudança quando um membro é acessado ou conjunto que pode ser feito sem alterar o contrato da classe.

A idéia é que, mesmo se as necessidades de estrutura de dados subjacentes para a mudança, a interface pública para a classe não terá que ser alterado.

C # pode tratar propriedades e variáveis ??de forma diferente às vezes. Por exemplo, você não pode passar propriedades como ref ou out parâmetros . Então, se você precisa mudar a estrutura de dados por alguma razão e você estava usando variáveis ??públicas e agora você precisa usar propriedades, sua interface terá que mudar e agora o código que acessa propriedade x não pode continuar a elaborar como ele fez quando era variável x:

Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
     Console.WriteLine("x = {0}", pt.x);
     Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}

Usando propriedades desde o início evita este, e você pode se sentir livre para ajustar a implementação subjacente tanto quanto você precisa sem quebrar o código do cliente.

Setter e Getter permite adicionar camada de abstração adicional e em OOP pura você deve sempre acessar os objetos através da interface eles estão fornecendo para o mundo exterior ...

Considere este código, que você vai economizar em asp.net e que não seria possível sem o nível de abstração proporcionada pelos setters e getters:

class SomeControl
{

private string _SomeProperty  ;
public string SomeProperty 
{
  if ( _SomeProperty == null ) 
   return (string)Session [ "SomeProperty" ] ;
 else 
   return _SomeProperty ; 
}
}

Desde auto implementado getters leva o mesmo nome para a propriedade e as variáveis ??reais de armazenagem privada. Como você pode alterá-lo no futuro? Acho que o ponto está sendo dito é que o uso da auto implementado em vez de campo de modo que você pode mudá-lo no futuro, se no caso você precisa adicionar lógica para getter e setter.

Por exemplo:

public string x { get; set; }

e, por exemplo, você já usa o x um monte de vezes e você não quer quebrar seu código.

Como você muda o setter auto getter ... por exemplo, para setter só permitem definir um formato de número de telefone válido ... como você alterar o código para que somente a classe é ser mudança?

A minha ideia é adicionar uma nova variável privada e adicionar a mesma x getter e setter.

private string _x;

public string x { 
    get {return x}; 
    set {
        if (Datetime.TryParse(value)) {
            _x = value;
        }
    }; 
}

É isso que você quer dizer com tornando-se flexível?

Também deve ser considerado é o efeito da mudança de membros públicos quando se trata de ligação e serialização. Ambos muitas vezes dependem de propriedades públicas para recuperar e valores definidos.

Além disso, você pode colocar pontos de interrupção em getters e setters, mas você não pode nos campos.

AFAIK a interface CIL gerado é diferente. Se você alterar um membro do público a uma propriedade que você está mudando interface e necessidade pública, de reconstruir cada arquivo que usa essa classe. Isso não é necessário se você só mudar a implementação dos getters e setters.

Talvez apenas fazendo campos públicos você poderia leva-lo a um mais Anemic Modelo de Domínio .

Atenciosamente

Também é importante notar que você não pode fazer Auto Propriedades somente leitura e você não pode Inicializar-los em linha. Ambos são coisas que eu gostaria de ver em uma versão futura do .NET, mas eu acredito que você pode fazer nem em .NET 4.0.

As únicas vezes que usar um campo de apoio com propriedades nos dias de hoje é quando os meus classe implementa INotifyPropertyChanged e eu preciso para acionar o evento OnPropertyChanged quando uma propriedade é alterada.

Também nestas situações eu definir os campos de apoio directamente quando os valores são passados ??de um construtor (sem necessidade de tentar acionar o OnPropertyChangedEvent (o que seria NULL neste momento de qualquer maneira), em qualquer outro lugar eu uso o próprio imóvel.

Você nunca sabe se você pode não precisar de alguma tradução dos dados mais tarde. Você está preparado para que, se você esconder seus membros. Os usuários do seu aviso não vai classe se você adicionar a tradução já que a interface continua o mesmo.

A maior difrence é que, se alguma vez você mudar a sua estrutura interna, você pode ainda manter os getters e setters como é, mudando a sua lógica interna, sem ferir os usuários de seu API.

Se você tem que mudar o modo de obter x e y, neste caso, você poderia apenas adicionar as propriedades mais tarde. Isto é o que eu acho mais confuso. Se você usar variáveis ??membro públicas, você pode facilmente mudar isso para uma propriedade mais tarde, e usar variáveis ??privadas chamados _x e _y, se você precisa para armazenar o valor internamente.

Setters e getters são ruins, em princípio, (eles são uma má OO cheiro - eu parada curta de dizer que eles são um anti-padrão, porque eles realmente são, por vezes necessárias).

Não, não é tecnicamente nenhuma diferença e quando eu realmente quero partilhar o acesso a um objeto estes dias, eu ocasionalmente torná-lo público final em vez de adicionar um getter.

A forma setters e getters foram "Vendido" é que você pode precisar de saber que alguém está recebendo um valor ou alterar um -. Que só faz sentido com primitivos

saco de Propriedade objetos como DAOs, DTOs e objetos de exibição são excluídos desta regra, pois estes não são objetos em um real "OO Design" significado da palavra objeto. (Você não acha das "mensagens que passam" a um DAO, é simplesmente uma pilha de pares atributo / valor).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top