Co to jest {get; zestaw; } składnia w C #?


577

Uczę się ASP.NET MVC i potrafię czytać dokumenty w języku angielskim, ale tak naprawdę nie rozumiem, co dzieje się w tym kodzie:

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

Co to znaczy { get; set; }:?


4
Ogólnie pamiętaj - ustawiacze powodują, że Twój obiekt jest modyfikowalny, co jest złym pomysłem. getters naruszają „Powiedz obiektowi, co ma robić, nie proś go o informacje i sam nim manipuluj”. Ogólnie rzecz biorąc, domyślnie nie dodawaj seterów i getterów. Często będziesz ich potrzebować, ale zawsze powinieneś znaleźć prawdziwą potrzebę przed ich dodaniem. W szczególności setery prawie nigdy nie powinny być używane w kodzie produkcyjnym (dążyć do niezmienności tam, gdzie to możliwe, a gdy potrzebna jest mutacja, należy poprosić ją o mutację dla siebie, a nie ustawiać wartości).
Bill K

8
Wystarczy dodać coś ... Jeśli nie umieścisz {get; set;}, tworzysz pole, ale jeśli je umieścisz {get; set;}, tworzysz właściwość . Posiadanie właściwości może ułatwić niektóre rzeczy, szczególnie podczas pracy z Reflection.
Seichi

@ Seichi za pomocą get-settera również tworzy pole, ale to jest ukryte, zadeklarowane jako prywatne i zmodyfikowane przez automatycznie utworzone właściwości; wszystko to wykonane przez kompilator.
Jonathan Ramos

1
czy właściwości auto nie pokonują celu pól prywatnych ?
mireazma

Odpowiedzi:


567

Jest to tak zwana właściwość auto i jest w skrócie następująca (podobny kod zostanie wygenerowany przez kompilator):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}

93
Klaus, czy możesz wyjaśnić, co stanie się z tym kodem? Przydałoby się dokładniejsze wyjaśnienie.
TylerH,

3
Tak więc, dla pewności: to tak, jakbym przeciążył =operatora, ale tylko dla jednego konkretnego elementu, prawda?
Cześć Anioł

9
Dlaczego potrzebujemy prywatnego var. :-/ wstyd.
Oliver Dixon

2
@TylerH Powodem dla zmiennej prywatnej jest enkapsulacja, get / set zapewnia „bramkę” do pobrania lub ustawienia zmiennej. Chociaż istnieje wiele powodów, aby nie używać get / setters, ponieważ „bramka” może przerwać enkapsulację zmiennej prywatnej. (nie powinno być dostępne)
Alexander

4
Może to być oczywiste, ale chcę wyjaśnić, że skrót nie jest dosłownie skrótem. Oznacza to, że nie namejest tworzona żadna zmienna prywatna . Jeśli spróbujesz odwołać się do tej zmiennej prywatnej w klasie, zakończy się ona niepowodzeniem. Nie jestem pewien, jak to robi C #, ale zachowuje się tak, jakby istniała zmienna prywatna bez nazwy, do której nie można uzyskać dostępu w kodzie.
Denziloe

432

Tak więc, jak rozumiem, { get; set; }jest to „własność automatyczna”, która podobnie jak @Klaus i @Brandon powiedzieli, że jest skrótem do pisania właściwości z „polem zaplecza”. Więc w tym przypadku:

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

Jednak jeśli jesteś podobny do mnie - mniej więcej godzinę temu - tak naprawdę nie rozumiesz, jakie są właściwości i akcesoria , a także nie masz najlepszego zrozumienia niektórych podstawowych terminologii. MSDN to świetne narzędzie do nauki takich rzeczy, ale nie zawsze jest łatwe do zrozumienia dla początkujących. Spróbuję więc wyjaśnić to bardziej szczegółowo tutaj.

geti setakcesorami , co oznacza, że ​​mogą uzyskiwać dostęp do danych i informacji w polach prywatnych (zwykle z pola zaplecza ) i zwykle robią to z właściwości publicznych (jak widać w powyższym przykładzie).

Nie można zaprzeczyć, że powyższe stwierdzenie jest dość mylące, więc przejdźmy do kilku przykładów. Powiedzmy, że ten kod odnosi się do gatunków muzycznych. Dlatego w ramach klasy Gatunek chcemy różnych gatunków muzycznych. Powiedzmy, że chcemy mieć 3 gatunki: Hip Hop, Rock i Country. Aby to zrobić, użylibyśmy nazwy klasy do utworzenia nowych instancji tej klasy.

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)

Teraz, stworzyliśmy instancje klasy gatunku możemy ustawić nazwy rodzajowe używając „name” właściwość , która została powołana aż powyżej.

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

Możemy ustawić nazwę „g1” na Hip Hop, pisząc poniżej

g1.Name = "Hip Hop";

To, co się tutaj dzieje, jest trochę skomplikowane. Jak powiedziałem wcześniej, geti setuzyskaj dostęp do informacji z prywatnych pól, do których w innym przypadku nie miałbyś dostępu. getmoże tylko odczytać informacje z tego prywatnego pola i zwrócić je. setmoże zapisywać informacje tylko w tym prywatnym polu. Ale przez posiadające nieruchomość na obu geti setjesteśmy w stanie zrobić obie te funkcje. Pisząc g1.Name = "Hip Hop";, korzystamy z setfunkcji z naszej właściwości Name

setużywa niejawnej zmiennej o nazwie value. Zasadniczo oznacza to, że za każdym razem, gdy zobaczysz „wartość” w środku set, odnosi się to do zmiennej; zmienna „wartość”. Kiedy piszemy g1.Name =, używamy =do przekazania valuezmiennej, która w tym przypadku jest "Hip Hop". Możesz zasadniczo myśleć o tym w ten sposób:

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"'
    }
}

Należy zauważyć, że powyższy przykład nie jest tak naprawdę zapisany w kodzie. To bardziej hipotetyczny kod, który reprezentuje to, co dzieje się w tle.

Więc teraz, kiedy ustawiliśmy nazwę instancji g1 gatunku , wierzę, że możemy uzyskać nazwę pisząc

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"

i gdybyśmy to uruchomili, dostalibyśmy się "Hip Hop"na konsolę.

Dla celów tego objaśnienia uzupełnię również przykład o dane wyjściowe

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);
    }
}

Wynik:

"Genres: Hip Hop, Rock, Country"

18
Osobiście skomentowałbym to jako takieset{name = value;} // 'value' here is equal to "Hip Hop"
maksymiuk

2
@ iLoveUnicorns, jest tam w celu pozyskiwania danych . Pole kopii zapasowej zawiera rzeczywiste dane. Definicja właściwości faktycznie określa sposób dostępu do danych za pomocą metod geti set. Link, który podałem, ma świetny cytat od Johna Guttaga na górze strony. Poleciłbym przeczytać jego książkę lub nawet wziąć udział w tym darmowym kursie online
Josie Thompson

2
Nie możemy po prostu użyć: public class Genre{public string Name;} zamiast: public class Genre{ public string Name { get; set; }}. Mam na myśli, dlaczego potrzebujemy {get; zestaw; }?
user2048204,

1
Wygląda na to, że moja troska już się powtórzyła. Jeśli zadeklarujesz w ten sposób: „public string Name {get; set;}” i uzyskasz dostęp w ten sposób: g1.Name = „Hip Hop”; - to gdzie jest orientacja obiektowa? Nie potrzebuję nawet tak zwanego „pola wsparcia”. O ile mi chodzi, pole zaplecza nawet nie istnieje. Ponieważ mam dostęp tylko do pola publicznego. A jeśli pole publiczne jest „publiczne”, to nie jest zgodne z OO. Wróćmy do COBOL.
Baruch Atta

1
Świetna odpowiedź, ale jeśli jesteśmy pedantyczni, „set” jest mutatorem, a nie akcesorium.
pythlang

100

To są właściwości automatyczne

Zasadniczo inny sposób pisania właściwości z polem zaplecza.

public class Genre
{
    private string _name;

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

7
Co nazywa się „polem zaplecza”?
kn3l

4
@stackunderflow: Pole kopii zapasowej to miejsce, w którym przechowywane są dane. (co jest zwracane podczas używania geti trwało przy użyciu set). Jak szafka, do której geti setotwiera drzwi.
Grant Thomas

5
@stackunderflow: W tej odpowiedzi pole zaplecza to _name. We właściwości automatycznej pole podkładu jest ukryte.
Justin

36

Oto krótki sposób na zrobienie tego:

public class Genre
{
    private string _name;

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

33

Jest to skrót do ujawnienia członków danych jako publicznych, dzięki czemu nie trzeba jawnie tworzyć prywatnych członków danych. C # utworzy dla Ciebie prywatnego członka danych.

Możesz po prostu upublicznić członków danych bez korzystania z tego skrótu, ale jeśli zdecydujesz się zmienić implementację członka danych, aby mieć trochę logiki, musisz przerwać interfejs. Krótko mówiąc, jest to skrót do tworzenia bardziej elastycznego kodu.


2
Kelsey - czy możesz wyjaśnić, w jaki sposób ta składnia czyni go bardziej „elastycznym” kodem? Nie widzę tego Jeśli dodasz jakąkolwiek „logikę” do settera lub gettera, to w przypadku eteru (z prywatnymi danymi lub bez nich) nadal zepsujesz interfejs w obecnej postaci i będziesz potrzebować trochę kodowania.
Baruch Atta

18

Zasadniczo jest to skrót:

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

5
To nie odpowiada na pytanie. OP mówił o nieruchomościach.
theB

6
znam właściwości Get and Set, to przykład, który pomaga lepiej zrozumieć
Jirson Tavera


6

Są to akcesory do własności publicznej Nazwa.

Użyłbyś ich, aby uzyskać / ustawić wartość tej właściwości w instancji gatunku.


6

To właściwość automatycznie wdrażana. Jest to w zasadzie skrócony sposób tworzenia właściwości dla klasy w języku C #, bez konieczności definiowania dla nich zmiennych prywatnych. Są one zwykle używane, gdy nie jest wymagana dodatkowa logika podczas uzyskiwania lub ustawiania wartości zmiennej.

Możesz przeczytać więcej na temat Przewodnika programowania właściwości zaimplementowanych automatycznie MSDN .


6
  • Wzorzec get / set zapewnia strukturę, która pozwala na dodanie logiki podczas ustawiania („set”) lub pobierania („get”) instancji właściwości instancji klasy, co może być przydatne, gdy wymagana jest pewna logika tworzenia instancji własność.

  • Właściwość może mieć tylko moduł „get”, który jest wykonywany w celu uczynienia tej właściwości tylko do odczytu

  • Podczas implementowania wzorca get / set zmienna pośrednia jest używana jako kontener, w którym można umieścić wartość i wyodrębnić wartość. Zmienna pośrednia jest zwykle poprzedzona znakiem podkreślenia. ta zmienna pośrednia jest prywatna, aby zapewnić, że można uzyskać do niej dostęp tylko poprzez wywołania get / set. Zobacz odpowiedź Brandona, ponieważ jego odpowiedź demonstruje najczęściej stosowane konwencje składniowe do implementacji get / set.


5

Oznacza to, że jeśli utworzysz zmienną typu Gatunek, będziesz mógł uzyskać do niej dostęp jako właściwość

Genre oG = new Genre();
oG.Name = "Test";

5
Jeśli nie korzystasz z właściwości automatycznie zaimplementowanych, nadal możesz uzyskać do nich dostęp w ten sposób. tzn. AIP nie dotyczy dostępu z zewnątrz, ale deklaracji wewnątrz klasy.
abatishchev

4

Taka { get; set; }składnia nosi nazwę właściwości automatycznych, składnia C # 3.0

Do kompilacji musisz użyć Visual C # 2008 / csc v3.5 lub nowszej wersji. Ale możesz skompilować dane wyjściowe, które są tak niskie, jak .NET Framework 2.0 (nie jest wymagane środowisko wykonawcze ani klasy do obsługi tej funkcji).


4

W programie Visual Studio, jeśli zdefiniujesz właściwość Xw klasie i chcesz używać tej klasy tylko jako typu, po zbudowaniu projektu otrzymasz ostrzeżenie z informacją: „Pole X nigdy nie jest przypisane i zawsze ma swoją wartość domyślną wartość ” .

Dodając właściwość { get; set; }do X, nie otrzymasz tego ostrzeżenia.

Ponadto w Visual Studio 2013 i wyższych wersjach, dodając, { get; set; }możesz zobaczyć wszystkie odwołania do tej właściwości.

wprowadź opis zdjęcia tutaj


4

Zasadniczo jest to skrót. Możesz pisać public string Name { get; set; }jak w wielu przykładach, ale możesz także napisać:

private string _name;

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

Dlaczego jest używany? Można go użyć do filtrowania dostępu do właściwości, na przykład nie chcesz, aby nazwy zawierały liczby.

Dam ci przykład:

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;
        }
    }
}

Oficjalnie nazywa się to Auto-Implemented Properties i ma dobry nawyk czytania ( przewodnik po programowaniu ). Poleciłbym również wideo instruktażowe Właściwości C #: Po co używać „get” i „set” .


2

Get set to modyfikatory dostępu do właściwości. Pobierz odczytuje pole właściwości. Zestaw ustawia wartość właściwości. Uzyskaj jest jak dostęp tylko do odczytu. Zestaw przypomina dostęp tylko do zapisu. Aby użyć właściwości jako do odczytu, napisz zarówno get, jak i set.


1
Myślę, że get set nie są modyfikatorami dostępu, w rzeczywistości są akcesoriami. Modyfikatory dostępu są takie jak: publiczny, prywatny, wewnętrzny itp.
Rohit Arora,

1

Funkcja Get jest wywoływana, gdy właściwość pojawia się po prawej stronie (RHS). Zestaw jest wywoływany, gdy właściwość pojawia się po lewej stronie (LHS) symbolu „=”.

W przypadku właściwości zaimplementowanej automatycznie pole podkładu działa za sceną i nie jest widoczne.

Przykład:

public string Log { get; set; }

Natomiast w przypadku właściwości niezaimplementowanej automatycznie pole zaplecza jest z góry widoczne jako zmienna o prywatnym zasięgu.

Przykład:

private string log;

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

Warto również zauważyć, że „getter” i „setter” mogą używać innego „pola zaplecza”


To nie wydaje się odpowiadać na zadane pytanie.
TylerH

Podana wskazówka, kiedy wywoływane jest get & set. Wszystkie powyższe odpowiedzi sprawiają wrażenie, że pole zaplecza dla get & set jest takie samo. Ale tak nie jest. Moja odpowiedź jest więc bardzo istotna w odniesieniu do głównego pytania. Mam nadzieję, że się ze mną zgadzasz.
Bala

W przypadku właściwości generowanej automatycznie, o którą pyta pytanie, nie można stosować różnych pól pomocniczych dla gettera i settera; jest tylko jedno pole zaplecza. W przypadku właściwości nieautomatycznej (o której pytanie nie pyta) może nie być w ogóle pola zaplecza. Dodatkowo możesz napisać program z geterem po lewej stronie operatora przypisania i taki z setera po prawej stronie operatora przypisania. Zatem nie tylko wszystkie te informacje nie odpowiadają na zadane pytanie, ale są również błędne.
Servy

0

Zdefiniuj zmienne prywatne

Wewnątrz Konstruktora i załaduj dane

Utworzyłem Constant i ładuję dane ze stałej do klasy 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; }

}

0

Właściwość jest jak warstwa, która oddziela zmienną prywatną od innych elementów klasy. Ze świata zewnętrznego wydaje się, że właściwość jest tylko polem, do właściwości można uzyskać dostęp za pomocą .Property

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}"; } }
}

Pełna nazwa jest właściwością. Ten ze strzałką jest skrótem. Ze świata zewnętrznego możemy uzyskać dostęp do FullName w następujący sposób:

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

Dzwoniący nie dbają o to, jak zaimplementowałeś FullName. Ale w klasie możesz zmienić FullName, co tylko chcesz.

Sprawdź dokumentację Microsoft, aby uzyskać bardziej szczegółowe wyjaśnienia:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.