Apa {get; set; } sintaks dalam C #?

577

Saya belajar ASP.NET MVC dan saya bisa membaca dokumen bahasa Inggris, tetapi saya tidak begitu mengerti apa yang terjadi dalam kode ini:

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

Apa ini berarti: { get; set; }?

kn3l
sumber
4
Secara umum diingat - setter membuat objek Anda bisa berubah, ide yang buruk. getter melanggar "Katakan objek apa yang harus dilakukan, jangan minta informasi dan memanipulasi sendiri". Jadi secara umum, jangan tambahkan setter dan getter secara default. Anda akan sering membutuhkannya, tetapi Anda harus selalu menemukan kebutuhan nyata sebelum menambahkannya. Khususnya setter seharusnya hampir tidak pernah digunakan dalam kode produksi (Berjuang untuk kekekalan sedapat mungkin, dan ketika mutasi diperlukan Anda harus memintanya untuk bermutasi untuk Anda, tidak menetapkan nilai).
Bill K
8
Hanya untuk menambahkan sesuatu ... Jika Anda tidak membuat, {get; set;}Anda membuat Bidang tetapi jika Anda meletakkannya, {get; set;}Anda sedang membuat Properti . Memiliki properti dapat membuat beberapa hal lebih mudah terutama ketika bekerja dengan Reflection.
Seichi
@ Seichi menggunakan get-setter membuat Field juga, tapi yang ini disembunyikan, dinyatakan sebagai pribadi dan dimodifikasi oleh properti yang dibuat secara otomatis; semua itu dibuat oleh kompiler.
Jonathan Ramos
1
bukankah properti otomatis mengalahkan tujuan bidang pribadi ?
mireazma

Jawaban:

567

Ini adalah properti otomatis yang disebut, dan pada dasarnya adalah singkatan untuk berikut ini (kode yang sama akan dihasilkan oleh kompiler):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
Klaus Byskov Pedersen
sumber
93
Klaus, dapatkah Anda menjelaskan apa yang akan terjadi dengan kode ini? Ini bisa mendapat manfaat dari penjelasan yang lebih menyeluruh.
TylerH
3
Jadi, hanya untuk memastikan: itu seperti jika saya membebani =operator, tetapi hanya untuk satu elemen tertentu, bukan?
Hi-Angel
9
Mengapa kita membutuhkan var pribadi. :-/ malu.
Oliver Dixon
2
@ TylerH Alasan untuk variabel pribadi adalah enkapsulasi, get / set menyediakan "gerbang" untuk mendapatkan atau mengatur variabel. Meskipun ada banyak alasan untuk tidak menggunakan get / setters karena "gerbang" dapat memecah enkapsulasi variabel pribadi. (seharusnya tidak dapat diakses)
Alexander
4
Mungkin sudah jelas, tetapi saya ingin mengklarifikasi bahwa singkatan itu secara harfiah bukan singkatan untuk itu. Artinya, tidak ada variabel pribadi nameyang dibuat. Jika Anda mencoba merujuk variabel pribadi ini di dalam kelas, itu akan gagal. Saya tidak yakin bagaimana C # melakukannya, tetapi berperilaku seolah-olah ada variabel pribadi tanpa nama, yang tidak dapat Anda akses dalam kode Anda.
Denziloe
432

Jadi seperti yang saya pahami itu { get; set; }adalah "properti otomatis" yang sama seperti @ Klaus dan @Brandon katakan adalah singkatan untuk menulis properti dengan "bidang dukungan." Jadi dalam hal ini:

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

Namun jika Anda seperti saya - sekitar satu jam yang lalu - Anda tidak benar-benar memahami apa properti dan pengakses itu, dan Anda tidak memiliki pemahaman terbaik tentang beberapa terminologi dasar. MSDN adalah alat yang hebat untuk mempelajari hal-hal seperti ini, tetapi tidak selalu mudah dipahami untuk pemula. Jadi saya akan mencoba menjelaskan ini lebih mendalam di sini.

getdan setyang accesor , yang berarti mereka dapat akses data dan info di swasta bidang (biasanya dari bidang dukungan ) dan biasanya melakukannya dari publik properti (seperti yang Anda lihat dalam contoh di atas).

Tidak dapat disangkal bahwa pernyataan di atas cukup membingungkan, jadi mari kita masuk ke beberapa contoh. Katakanlah kode ini mengacu pada genre musik. Jadi di dalam Genre kelas, kita akan menginginkan genre musik yang berbeda. Katakanlah kita ingin memiliki 3 genre: Hip Hop, Rock, dan Country. Untuk melakukan ini kita akan menggunakan nama Kelas untuk membuat instance baru dari kelas itu.

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)

Sekarang kita telah menciptakan contoh dari kelas Genre kita dapat mengatur nama bergenre menggunakan 'Nama' properti itu cara set up di atas.

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

Kita dapat mengatur nama 'g1' ke Hip Hop dengan menulis yang berikut ini

g1.Name = "Hip Hop";

Apa yang terjadi di sini agak rumit. Seperti yang saya katakan sebelumnya, getdan setakses informasi dari bidang pribadi yang Anda tidak akan dapat mengakses. gethanya dapat membaca informasi dari bidang pribadi itu dan mengembalikannya. sethanya dapat menulis informasi di bidang pribadi itu. Tetapi dengan memiliki properti dengan keduanya getdan setkami dapat melakukan kedua fungsi tersebut. Dan dengan menulis g1.Name = "Hip Hop";kami secara khusus menggunakan setfungsi dari properti Nama kami

setmenggunakan variabel implisit yang disebut value. Pada dasarnya apa artinya ini setiap kali Anda melihat "nilai" di setdalamnya, itu merujuk ke variabel; variabel "nilai". Ketika kita menulis, g1.Name =kita menggunakan =untuk meneruskan valuevariabel yang dalam hal ini adalah "Hip Hop". Jadi pada dasarnya Anda bisa memikirkannya seperti ini:

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

Penting untuk dicatat bahwa contoh di atas sebenarnya tidak ditulis dalam kode. Ini lebih merupakan kode hipotetis yang mewakili apa yang terjadi di latar belakang.

Jadi sekarang kita telah menetapkan Nama g1 dari Genre , saya yakin kita bisa mendapatkan namanya dengan menulis

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"

dan jika kita menjalankan ini kita akan masuk "Hip Hop"ke konsol kita.

Jadi untuk tujuan penjelasan ini saya akan melengkapi contoh dengan output juga

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

Keluaran:

"Genres: Hip Hop, Rock, Country"
Josie Thompson
sumber
18
Secara pribadi saya hanya akan berkomentar seperti ituset{name = value;} // 'value' here is equal to "Hip Hop"
maksymiuk
2
@ iLoveUnicorns, ada di sana untuk tujuan abstraksi data . Bidang dukungan adalah yang berisi data aktual. Definisi properti sebenarnya mendefinisikan bagaimana data diakses dengan getdan setmetode. Tautan yang saya berikan memiliki kutipan yang sangat baik dari John Guttag di bagian atas halaman. Saya akan merekomendasikan membaca bukunya atau bahkan mengambil kursus online gratis ini
Josie Thompson
2
Kita tidak bisa hanya menggunakan: public class Genre{public string Name;} bukan: public class Genre{ public string Name { get; set; }}. Maksud saya, mengapa kita perlu {get; set; }?
user2048204
1
Sepertinya kekhawatiran saya sudah digaungkan. Jika Anda menyatakan seperti ini: "public string Name {get; set;}" dan Anda mengaksesnya: g1.Name = "Hip Hop"; - lalu di mana Orientasi Objek? Saya bahkan tidak membutuhkan apa yang disebut "bidang dukungan". Bidang dukungan bahkan tidak ada, sejauh yang saya ketahui. Karena saya hanya mengakses bidang publik. Dan jika bidang publik adalah "publik" maka itu tidak sesuai dengan OO. Mari kita semua kembali ke COBOL.
Baruch Atta
1
Jawaban yang bagus, tetapi jika kita menjadi orang yang bertele-tele, "set" adalah mutator, bukan accessor.
pythlang
100

Itu adalah properti otomatis

Pada dasarnya cara lain menulis properti dengan bidang dukungan.

public class Genre
{
    private string _name;

    public string Name 
    { 
      get => _name;
      set => _name = value;
    }
}
Brandon
sumber
7
Apa yang disebut "bidang dukungan"?
kn3l
4
@stackunderflow: Bidang dukungan adalah tempat data disimpan. (apa yang dikembalikan saat menggunakan get, dan tetap menggunakan set). Seperti lemari tempat getdan setmembuka pintu.
Berikan Thomas
5
@stackunderflow: Dalam jawaban ini, bidang dukungan adalah _name. Di properti otomatis, bidang dukungan disembunyikan.
Justin
36

Ini adalah cara singkat untuk melakukan ini:

public class Genre
{
    private string _name;

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

Ini adalah jalan pintas untuk mengekspos anggota data sebagai publik sehingga Anda tidak perlu secara eksplisit membuat anggota data pribadi. C # akan membuat anggota data pribadi untuk Anda.

Anda bisa membuat anggota data Anda menjadi publik tanpa menggunakan cara pintas ini tetapi kemudian jika Anda memutuskan untuk mengubah implementasi anggota data untuk memiliki beberapa logika maka Anda perlu memecah antarmuka. Jadi singkatnya itu adalah jalan pintas untuk membuat kode yang lebih fleksibel.

Kelsey
sumber
2
Kelsey - dapatkah Anda menjelaskan bagaimana sintaks ini membuatnya menjadi kode yang lebih "fleksibel"? Saya tidak melihatnya. Jika Anda ingin menambahkan "logika" ke setter atau pengambil, maka dalam kasus eter (dengan atau tanpa data pribadi) Anda masih akan merusak antarmuka, seperti apa adanya, dan perlu beberapa pengkodean.
Baruch Atta
18

Pada dasarnya, ini adalah jalan pintas dari:

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
sumber
5
Ini tidak menjawab pertanyaan. OP berbicara tentang properti.
theB
6
saya tahu properti Get and Set, ini adalah contoh yang membantu memahami dengan lebih baik
Jirson Tavera
10

Ini properti yang diimplementasikan secara otomatis untuk C #.

Daniel A. White
sumber
1
Eh ... Apakah ini berarti Anda menyimpan referensi nol ke string dan kemudian memuat nilainya dari lokasi standar saat get; set;dipanggil?
Aurum Aquila
1
Ya itu tetap nullseperti stringvariabel apa pun sampaisomeInstanceOfGenere.Name = "someValue"
Daniel A. White
6

Mereka adalah penentu untuk Nama properti publik.

Anda akan menggunakannya untuk mendapatkan / menetapkan nilai properti itu dalam instance Genre.

TimCodes.NET
sumber
6

Itu adalah Properti yang Diimplementasikan Secara Otomatis. Ini pada dasarnya cara singkat membuat properti untuk kelas di C #, tanpa harus mendefinisikan variabel pribadi untuk mereka. Mereka biasanya digunakan ketika tidak ada logika tambahan yang diperlukan ketika mendapatkan atau mengatur nilai suatu variabel.

Anda dapat membaca lebih lanjut tentang Panduan Pemrograman Properti yang Diterapkan Otomatis MSDN .

Dusda
sumber
6
  • Pola get / set menyediakan struktur yang memungkinkan logika untuk ditambahkan selama pengaturan ('set') atau pengambilan ('get') dari instance properti dari kelas instantiated, yang dapat berguna ketika beberapa logika instantiation diperlukan untuk Properti.

  • Properti dapat memiliki aksesor 'dapatkan' saja, yang dilakukan untuk menjadikan properti tersebut hanya-baca

  • Saat menerapkan pola get / set, variabel perantara digunakan sebagai wadah di mana nilai dapat ditempatkan dan nilai diekstraksi. Variabel perantara biasanya diawali dengan garis bawah. variabel perantara ini bersifat pribadi untuk memastikan bahwa ia hanya dapat diakses melalui panggilan get / set. Lihat jawaban dari Brandon, karena jawabannya menunjukkan konvensi sintaksis yang paling umum digunakan untuk mengimplementasikan get / set.

Chris Halcrow
sumber
5

Ini berarti bahwa jika Anda membuat variabel jenis Genre, Anda akan dapat mengakses variabel sebagai properti

Genre oG = new Genre();
oG.Name = "Test";
David Brunelle
sumber
5
Ketika Anda tidak menggunakan properti yang diimplementasikan secara otomatis, Anda masih dapat mengaksesnya dengan cara ini. yaitu AIP bukan tentang akses dari luar, tetapi tentang deklarasi di dalam kelas.
abatishchev
4

{ get; set; }Sintaksis seperti ini disebut properti otomatis, sintaksis C # 3.0

Anda harus menggunakan Visual C # 2008 / csc v3.5 atau lebih tinggi untuk mengkompilasi. Tetapi Anda dapat mengkompilasi output yang menargetkan serendah .NET Framework 2.0 (tidak perlu runtime atau kelas untuk mendukung fitur ini).

linquize
sumber
4

Di Visual Studio, jika Anda mendefinisikan properti Xdi kelas dan Anda ingin menggunakan kelas ini hanya sebagai tipe, setelah membangun proyek Anda, Anda akan mendapatkan peringatan yang mengatakan "Bidang X tidak pernah ditugaskan, dan akan selalu memiliki standarnya nilai" .

Dengan menambahkan { get; set; }keX properti , Anda tidak akan mendapatkan peringatan ini.

Selain itu di Visual Studio 2013 dan versi atas, dengan menambahkan { get; set; }Anda dapat melihat semua referensi ke properti itu.

masukkan deskripsi gambar di sini

Omid Ebrahimi
sumber
4

Ini pada dasarnya sebuah steno. Anda dapat menulis public string Name { get; set; }seperti dalam banyak contoh, tetapi Anda juga dapat menulisnya:

private string _name;

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

Kenapa digunakan? Ini dapat digunakan untuk memfilter akses ke properti, misalnya Anda tidak ingin nama menyertakan angka.

Biarkan saya memberi Anda sebuah contoh:

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

Secara resmi disebut Properti Diterapkan-Otomatis dan kebiasaan yang baik untuk membaca ( panduan pemrograman ). Saya juga akan merekomendasikan video tutorial C # Properties: Mengapa menggunakan "get" dan "set" .

Randel
sumber
2

Set adalah pengubah akses ke properti. Baca bidang properti. Set mengatur nilai properti. Dapatkan seperti akses hanya baca. Set seperti akses hanya-tulis. Untuk menggunakan properti sebagai baca tulis, get dan set harus digunakan.

Ashraf Abusada
sumber
1
Saya pikir mendapatkan set tidak mengakses pengubah, pada kenyataannya mereka adalah accessors. Pengubah akses seperti: publik, pribadi, internal dll.
Rohit Arora
1

Get dipanggil ketika properti muncul di sisi kanan (RHS) Set dipanggil ketika properti muncul di sisi kiri (LHS) dari simbol '='

Untuk properti yang diimplementasikan secara otomatis, bidang dukungan bekerja di belakang layar dan tidak terlihat.

Contoh:

public string Log { get; set; }

Sedangkan untuk properti yang tidak diimplementasikan otomatis, bidang dukungan di muka, terlihat sebagai variabel cakupan pribadi.

Contoh:

private string log;

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

Juga, perlu dicatat di sini adalah 'pengambil' dan 'penyetel' dapat menggunakan 'bidang dukungan' yang berbeda

Bala
sumber
Ini sepertinya tidak menjawab pertanyaan yang diajukan.
TylerH
Memberikan petunjuk kapan get & set dipanggil. Semua jawaban yang disebutkan di atas, membuat kesan bahwa bidang dukungan untuk get & set adalah sama. Tapi bukan itu masalahnya. Jadi jawaban saya sangat relevan dengan pertanyaan utama. Semoga Anda setuju dengan saya.
Bala
Untuk properti yang dibuat secara otomatis, yang merupakan pertanyaan yang ditanyakan, tidak ada bidang dukungan yang berbeda yang digunakan untuk pengambil dan penyetel; hanya ada satu bidang dukungan. Untuk properti non-otomatis (yang tidak ditanyakan oleh pertanyaan) bahkan mungkin tidak ada bidang dukungan sama sekali. Selain itu, Anda dapat menulis program dengan pengambil di sisi kiri operator penugasan dan satu dengan setter di sisi kanan operator penugasan. Jadi tidak hanya semua informasi ini tidak menjawab pertanyaan yang diajukan, tetapi semua juga salah.
Servy
0

Tentukan variabel Private

Di dalam konstruktor dan memuat data

Saya telah membuat Constant dan memuat data dari konstanta ke kelas Daftar yang Dipilih.

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
sumber
0

Properti adalah seperti lapisan yang memisahkan variabel pribadi dari anggota kelas lainnya. Dari dunia luar rasanya seperti properti hanya bidang, properti dapat diakses menggunakan .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}"; } }
}

FullName adalah Properti. Yang dengan panah adalah jalan pintas. Dari dunia luar, kita dapat mengakses FullName seperti ini:

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

Penelepon tidak peduli tentang bagaimana Anda menerapkan Nama Lengkap. Namun di dalam kelas Anda dapat mengubah FullName apa pun yang Anda inginkan.

Lihat Dokumentasi Microsoft untuk penjelasan lebih rinci:

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

MING WU
sumber