O que é o {get; conjunto; } sintaxe em c #?

577

Estou aprendendo o ASP.NET MVC e posso ler documentos em inglês, mas realmente não entendo o que está acontecendo neste código:

public class Genre
{
    public string Name { get; set; }
}

O que isso significa { get; set; }:?

kn3l
fonte
4
Em geral, lembre-se: os criadores tornam seu objeto mutável, uma má idéia. getters violam "Diga a um objeto o que fazer, não peça informações e manipule você mesmo". Portanto, em geral, não adicione setters e getters por padrão. Você precisará deles frequentemente, mas sempre deve encontrar uma necessidade real antes de adicioná-los. Em particular, os setters quase nunca devem ser usados ​​no código de produção (lute pela imutabilidade sempre que possível, e quando a mutação for necessária, você deve pedir que ele faça uma mutação para você, não defina um valor).
Bill K
8
Apenas para adicionar algo ... Se você não colocar, {get; set;}está criando um Campo, mas se você colocar, {get; set;}está criando uma Propriedade . Ter uma propriedade pode facilitar algumas coisas, especialmente quando se trabalha com o Reflection.
Seichi 04/04
@Seichi usando um get-setter também cria um campo, mas este está oculto, declarado como privado e modificado pelas propriedades criadas automaticamente; tudo isso feito pelo compilador.
Jonathan Ramos
1
as propriedades automáticas não derrotam o objetivo dos campos particulares ?
mireazma

Respostas:

567

É uma propriedade chamada auto e é essencialmente uma abreviação para o seguinte (código semelhante será gerado pelo compilador):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
Klaus Byskov Pedersen
fonte
93
Klaus, você pode explicar o que acontecerá com esse código? Poderia se beneficiar de uma explicação mais completa.
TylerH
3
Então, só para ter certeza: é como se eu sobrecarregasse o =operador, mas apenas para um elemento em particular, certo?
Hi-Angel
9
Por que precisamos do var privado. :-/ vergonha.
Oliver Dixon
2
@TylerH O motivo da variável privada é o encapsulamento, o get / set fornece um "gate" para obter ou definir a variável. Embora existam muitas razões para não usar get / setters, porque o "gate" pode quebrar o encapsulamento da variável privada. (que não deve ser acessível)
Alexander
4
Pode ser óbvio, mas quero esclarecer que a abreviação não é literalmente uma abreviação para isso. Ou seja, nenhuma variável privada nameé criada. Se você tentou fazer referência a essa variável privada dentro da classe, ela falhará. Não tenho certeza de como o C # faz isso, mas se comporta como se houvesse uma variável privada sem nome, que você não pode acessar no seu código.
Denziloe 9/02/19
432

Pelo que entendi, { get; set; }é uma "propriedade automática" que, como @Klaus e @Brandon disseram, é uma abreviação para escrever uma propriedade com um "campo de apoio". Então, neste caso:

public class Genre
{
    private string name; // This is the backing field
    public string Name   // This is your property
    {
        get => name;
        set => name = value;
    }
}

No entanto, se você é como eu - cerca de uma hora atrás - você realmente não entende o que são propriedades e acessadores e também não tem o melhor entendimento de algumas terminologias básicas. O MSDN é uma ótima ferramenta para aprender coisas como essa, mas nem sempre é fácil de entender para iniciantes. Então, vou tentar explicar isso mais profundamente aqui.

gete setsão acessadores , o que significa que eles podem acessar dados e informações em campos particulares (geralmente de um campo de apoio ) e geralmente de propriedades públicas (como você pode ver no exemplo acima).

Não há como negar que a declaração acima é bastante confusa, então vamos dar alguns exemplos. Digamos que esse código esteja se referindo a gêneros musicais. Então, dentro da classe Gênero, vamos querer diferentes gêneros musicais. Digamos que queremos ter três gêneros: Hip Hop, Rock e Country. Para fazer isso, usaríamos o nome da classe para criar novas instâncias dessa classe.

Genre g1 = new Genre(); //Here we're creating a new instance of the class "Genre"
                        //called g1. We'll create as many as we need (3)
Genre g2 = new Genre();
Genre g3 = new Genre();

//Note the () following new Genre. I believe that's essential since we're creating a
//new instance of a class (Like I said, I'm a beginner so I can't tell you exactly why
//it's there but I do know it's essential)

Agora que criamos as instâncias da classe Genre, podemos definir os nomes dos gêneros usando a propriedade 'Name' que foi configurada acima.

public string Name //Again, this is the 'Name' property
{ get; set; } //And this is the shorthand version the process we're doing right now 

Podemos definir o nome de 'g1' para Hip Hop, escrevendo o seguinte

g1.Name = "Hip Hop";

O que está acontecendo aqui é meio complexo. Como eu disse antes, gete setacesse informações de campos particulares que você não conseguiria acessar. getsó pode ler informações desse campo privado e devolvê-las. setsó pode gravar informações nesse campo privado. Mas, tendo uma propriedade com ambos gete setsomos capazes de executar essas duas funções. E, escrevendo g1.Name = "Hip Hop";, estamos especificamente usando a setfunção da nossa propriedade Name

setusa uma variável implícita chamada value. Basicamente, o que isso significa é que sempre que você vê "valor" set, está se referindo a uma variável; a variável "value". Quando escrevemos g1.Name =, estamos usando o =para passar a valuevariável que, neste caso, é "Hip Hop". Então você pode essencialmente pensar assim:

public class g1 //We've created an instance of the Genre Class called "g1"
{
    private string name;
    public string Name
    {
        get => name;
        set => name = "Hip Hop"; //instead of 'value', "Hip Hop" is written because 
                              //'value' in 'g1' was set to "Hip Hop" by previously
                              //writing 'g1.Name = "Hip Hop"'
    }
}

É importante observar que o exemplo acima não está realmente escrito no código. É mais um código hipotético que representa o que está acontecendo em segundo plano.

Então agora que definimos o nome da instância g1 do gênero , acredito que podemos obter o nome escrevendo

console.WriteLine (g1.Name); //This uses the 'get' function from our 'Name' Property 
                             //and returns the field 'name' which we just set to
                             //"Hip Hop"

e se rodássemos isso, entraríamos "Hip Hop"em nosso console.

Portanto, para o propósito desta explicação, completarei o exemplo com saídas também

using System;
public class Genre
{
    public string Name { get; set; }
}

public class MainClass
{
    public static void Main()
    {
        Genre g1 = new Genre();
        Genre g2 = new Genre();
        Genre g3 = new Genre();

        g1.Name = "Hip Hop";
        g2.Name = "Rock";
        g3.Name = "Country";

        Console.WriteLine ("Genres: {0}, {1}, {2}", g1.Name, g2.Name, g3.Name);
    }
}

Resultado:

"Genres: Hip Hop, Rock, Country"
Josie Thompson
fonte
18
Pessoalmente gostaria apenas comentá-la como talset{name = value;} // 'value' here is equal to "Hip Hop"
Maksymiuk
2
@iLoveUnicorns, está lá com o objetivo de abstração de dados . O campo de suporte é o que contém os dados reais. A definição da propriedade realmente define como os dados são acessados ​​com os métodos gete set. O link que forneci tem uma excelente citação de John Guttag na parte superior da página. Eu recomendaria ler seu livro ou mesmo tomar este curso online gratuito
Josie Thompson
2
Não podemos apenas usar: public class Genre{public string Name;} em vez de: public class Genre{ public string Name { get; set; }}. Quero dizer, por que precisamos de {get; conjunto; }?
precisa saber é o seguinte
1
Parece que minha preocupação já foi ecoada. Se você declarar desta maneira: "public string Name {get; set;}" e você acessa desta maneira: g1.Name = "Hip Hop"; - então onde está a orientação a objetos? Eu nem preciso do chamado "campo de apoio". O campo de apoio nem existe, no que me diz respeito. Porque eu só acesso o campo público. E se o campo público for "público", não será compatível com OO. Vamos todos voltar ao COBOL.
Baruch Atta
1
Ótima resposta, mas se estamos sendo pedantes, "set" é um mutador, não um acessador.
Pythlang 17/05/19
100

Essas são propriedades automáticas

Basicamente, outra maneira de escrever uma propriedade com um campo de apoio.

public class Genre
{
    private string _name;

    public string Name 
    { 
      get => _name;
      set => _name = value;
    }
}
Brandon
fonte
7
O que é chamado de "campo de apoio"?
kn3l
4
@stackunderflow: o campo de suporte é o local onde os dados são armazenados. (o que é retornado ao usar gete persistiu usando set). Como o armário para o qual gete setabre a porta.
Grant Thomas
5
@ stackunderflow: nesta resposta, o campo de apoio é _name. Na propriedade automática, o campo de suporte está oculto.
Justin
36

Esta é a maneira curta de fazer isso:

public class Genre
{
    private string _name;

    public string Name
    {
      get => _name;
      set => _name = value;
    }
}
froeschli
fonte
33

É um atalho para expor membros de dados como públicos, para que você não precise criar explicitamente membros de dados privados. O C # cria um membro de dados privado para você.

Você pode apenas tornar seus membros de dados públicos sem usar esse atalho, mas se você decidir alterar a implementação do membro de dados para ter alguma lógica, precisará interromper a interface. Portanto, em resumo, é um atalho para criar código mais flexível.

Kelsey
fonte
2
Kelsey - você poderia explicar como essa sintaxe torna o código mais "flexível"? Eu não vejo isso. Se você adicionasse qualquer "lógica" ao setter ou getter, então no caso ether (com ou sem dados privados) você ainda quebraria a interface, como está, e precisará de alguma codificação.
Baruch Atta
18

Basicamente, é um atalho de:

class Genre{
    private string genre;
    public string getGenre() {
        return this.genre;
    }
    public void setGenre(string theGenre) {
        this.genre = theGenre;
    }
}
//In Main method
genre g1 = new Genre();
g1.setGenre("Female");
g1.getGenre(); //Female
Jirson Tavera
fonte
5
Isso não responde à pergunta. O OP estava falando sobre propriedades.
theB
6
eu sei que as propriedades Get e Set, que é um exemplo que ajuda a compreender melhor
Jirson Tavera
10

É uma propriedade implementada automaticamente para C #.

Daniel A. White
fonte
1
Eh ... Isso significa que você mantém nula referência à string e carrega seu valor de um local padrão quando get; set;é chamado?
Aurum Aquila
1
Sim, ele permanece nullcomo qualquer stringvariável atésomeInstanceOfGenere.Name = "someValue"
Daniel A. White
6

Eles são os acessadores do nome da propriedade pública.

Você os usaria para obter / definir o valor dessa propriedade em uma instância de Genre.

TimCodes.NET
fonte
6

Essa é uma propriedade implementada automaticamente. É basicamente uma maneira abreviada de criar propriedades para uma classe em C #, sem precisar definir variáveis ​​particulares para elas. Eles são normalmente usados ​​quando nenhuma lógica extra é necessária ao obter ou definir o valor de uma variável.

Você pode ler mais no Guia de Programação de Propriedades Auto-Implementadas do MSDN .

Dusda
fonte
6
  • O padrão get / set fornece uma estrutura que permite que a lógica seja adicionada durante a configuração ('set') ou a recuperação ('get') de uma instância de propriedade de uma classe instanciada, o que pode ser útil quando alguma lógica de instanciação for necessária para o método propriedade.

  • Uma propriedade pode ter apenas um acessador 'get', o que é feito para tornar essa propriedade somente leitura

  • Ao implementar um padrão get / set, uma variável intermediária é usada como um contêiner no qual um valor pode ser colocado e um valor extraído. A variável intermediária geralmente é prefixada com um sublinhado. essa variável intermediária é privada para garantir que só possa ser acessada através de suas chamadas get / set. Veja a resposta de Brandon, pois sua resposta demonstra as convenções de sintaxe mais usadas para implementar o get / set.

Chris Halcrow
fonte
5

Isso significa que, se você criar uma variável do tipo Genre, poderá acessar a variável como uma propriedade

Genre oG = new Genre();
oG.Name = "Test";
David Brunelle
fonte
5
Quando você não usa propriedades implementadas automaticamente, ainda é possível acessá-las dessa maneira. isto é, o AIP não é sobre acesso externo, mas sobre declaração dentro de uma classe.
23611 abatishchev
4

Essa { get; set; }sintaxe é chamada de propriedades automáticas, sintaxe C # 3.0

Você deve usar o Visual C # 2008 / csc v3.5 ou superior para compilar. Mas você pode compilar uma saída que tenha como alvo o .NET Framework 2.0 (sem tempo de execução ou classes necessárias para oferecer suporte a esse recurso).

ceder
fonte
4

No Visual Studio, se você definir uma propriedade Xem uma classe e quiser usá-la apenas como um tipo, depois de criar seu projeto, receberá um aviso dizendo "O campo X nunca é atribuído e sempre terá seu padrão". valor " .

Ao adicionar um { get; set; }a Xpropriedade, você não vai conseguir este aviso.

Além disso, no Visual Studio 2013 e nas versões superiores, adicionando { get; set; }você poderá ver todas as referências a essa propriedade.

insira a descrição da imagem aqui

Omid Ebrahimi
fonte
4

É basicamente uma taquigrafia. Você pode escrever public string Name { get; set; }como em muitos exemplos, mas também pode escrever:

private string _name;

public string Name
{
    get { return _name; }
    set { _name = value ; } // value is a special keyword here
}

Por que é usado? Ele pode ser usado para filtrar o acesso a uma propriedade, por exemplo, você não deseja que os nomes incluam números.

Deixe-me lhe dar um exemplo:

private class Person {
    private int _age;  // Person._age = 25; will throw an error
    public int Age{
        get { return _age; }  // example: Console.WriteLine(Person.Age);
        set { 
            if ( value >= 0) {
                _age = value; }  // valid example: Person.Age = 25;
        }
    }
}

Oficialmente, é chamado Propriedades Auto-Implementadas e seu bom hábito de ler o ( guia de programação ). Eu também recomendaria o vídeo tutorial C # Properties: Por que usar "get" e "set" .

Randel
fonte
2

Conjunto são modificadores de acesso à propriedade. Get lê o campo da propriedade. Set define o valor da propriedade. Get é como acesso somente leitura. Conjunto é como acesso somente gravação. Para usar a propriedade como leitura, gravação, get e set devem ser usados.

Ashraf Abusada
fonte
1
Eu acho que se preparar não são modificadores de acesso, na verdade eles são acessadores. Os modificadores de acesso são como: público, privado, interno etc.
Rohit Arora
1

Get é chamado quando a propriedade aparece no lado direito (RHS) O conjunto é chamado quando a propriedade aparece no lado esquerdo (LHS) do símbolo '='

Para uma propriedade implementada automaticamente, o campo de suporte funciona nos bastidores e não é visível.

Exemplo:

public string Log { get; set; }

Enquanto que para uma propriedade não implementada automaticamente, o campo de suporte é inicial, visível como uma variável de escopo particular.

Exemplo:

private string log;

public string Log
{
    get => log;
    set => log = value;
}

Além disso, vale ressaltar aqui que o 'getter' e o 'setter' podem usar os diferentes 'campos de apoio'

Bala
fonte
Isso não parece responder à pergunta.
TylerH
Dica fornecida quando o get & set é chamado. Todas as respostas mencionadas acima dão a impressão de que o campo de suporte para obter e definir é o mesmo. Mas não é o caso. Portanto, minha resposta é muito relevante para a questão principal. Espero que você concorde comigo.
Bala
Para uma propriedade gerada automaticamente, que é a pergunta que faz, não pode haver diferentes campos de apoio usados ​​para o getter e o setter; existe apenas um campo de apoio. Para uma propriedade não-automática (sobre a qual a pergunta não pergunta), pode não haver nem mesmo um campo de apoio conceitualmente. Além disso, você pode escrever um programa com um getter no lado esquerdo de um operador de atribuição e outro com um setter no lado direito de um operador de atribuição. Portanto, todas essas informações não apenas não respondem à pergunta, mas também estão erradas.
Servy
0

Definir as variáveis ​​privadas

Dentro do Construtor e carregue os dados

Criei Constant e carregue os dados da constante na classe Selected List.

public  class GridModel
{
    private IEnumerable<SelectList> selectList;
    private IEnumerable<SelectList> Roles;

    public GridModel()
    {
        selectList = from PageSizes e in Enum.GetValues(typeof(PageSizes))
                       select( new SelectList()
                       {
                           Id = (int)e,
                           Name = e.ToString()
                       });

        Roles= from Userroles e in Enum.GetValues(typeof(Userroles))
               select (new SelectList()
               {
                   Id = (int)e,
                   Name = e.ToString()
               });
    }

  public IEnumerable<SelectList> Pagesizelist { get { return this.selectList; } set { this.selectList = value; } } 
  public IEnumerable<SelectList> RoleList { get { return this.Roles; } set { this.Roles = value; } }
  public IEnumerable<SelectList> StatusList { get; set; }

}
Hari Lakkakula
fonte
0

Uma propriedade é como uma camada que separa a variável privada de outros membros de uma classe. Do mundo exterior, parece que uma propriedade é apenas um campo, uma propriedade pode ser acessada usando.

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return $"{FirstName} {LastName}"; } }
}

FullName é uma propriedade. O da seta é um atalho. Do mundo exterior, podemos acessar o FullName assim:

var person = new Person();
Console.WriteLine(person.FullName);

Os chamadores não se importam com a maneira como você implementou o FullName. Mas, dentro da classe, você pode alterar o Nome completo conforme desejar.

Confira a documentação da Microsoft para obter explicações mais detalhadas:

https://docs.microsoft.com/en-us/dotnet/csharp/properties

MING WU
fonte