{取得とは; セットする; C#の構文?


577

私はASP.NET MVCを学習していて、英語のドキュメントを読むことができますが、このコードで何が起こっているのか本当に理解できません。

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

これはどういう意味{ get; set; }ですか?


4
一般に、セッターはオブジェクトを変更可能にすることをお勧めします。悪い考えです。ゲッターは「オブジェクトに何をすべきかを伝え、情報を要求したり自分で操作したりしない」に違反します。したがって、一般に、デフォルトではセッターとゲッターを追加しないでください。それらは頻繁に必要になりますが、追加する前に常に実際のニーズを見つける必要があります。特に、setterは本番用コードではほとんど使用しないでください(可能な限り不変性を追求し、変更が必要な場合は、値を設定するのではなく、変更を依頼する必要があります)。
ビルK

8
何かを追加するだけです...配置しない{get; set;}場合はフィールドを作成しますが、配置する{get; set;}場合はプロパティを作成します。プロパティがあると、特にReflectionで作業するときに、いくつかのことが簡単になります。
Seichi

@Seichiはget-setterを使用してフィールドも作成しますが、これは非表示にされ、プライベートとして宣言され、自動作成されたプロパティによって変更されます。コンパイラによって作成されたものすべて。
ジョナサンラモス

1
自動プロパティはプライベートフィールドの目的を無効にしませんか?
mireazma

回答:


567

これはいわゆるautoプロパティであり、基本的には次の省略形です(同様のコードがコンパイラーによって生成されます)。

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

93
クラウス、このコードで何が起こるか説明できますか?より完全な説明から利益を得ることができます。
TylerH 2014年

3
だから、念のために言うと、=演算子をオーバーロードしたようなものですが、特定の1つの要素に対してのみですよね?
Hi-Angel

9
なぜプライベート変数が必要なのですか?:-/残念。
Oliver Dixon

2
@TylerHプライベート変数の理由はカプセル化であり、get / setは変数を取得または設定するための「ゲート」を提供します。「ゲート」はプライベート変数のカプセル化を壊す可能性があるため、get / setterを使用しない理由はたくさんありますが。(アクセスできないようにする必要があります)
Alexander

4
当たり前かもしれませんが、速記は文字通りその速記ではないことを明確にしたいと思います。つまり、プライベート変数nameは作成されません。クラス内でこのプライベート変数を参照しようとすると、失敗します。C#がどのように実行するかはわかりませんが、コードでアクセスできない名前のないプライベート変数があるかのように動作します。
Denziloe

432

つまり、私が理解して{ get; set; }いるように、これは「自動プロパティ」であり、@ Klausや@Brandonが言ったように、「バッキングフィールド」を持つプロパティを記述するための省略形です。したがって、この場合:

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

ただし、私と同じように-1時間ほど前に- プロパティアクセサーが何であるか本当に理解しておらず、いくつかの基本的な用語についてもよく理解していません。MSDNは、このようなものを学習するための優れたツールですが、初心者にとって必ずしも理解しやすいとは限りません。ここでは、これについて詳しく説明します。

getおよびsetアクセサーです。つまり、プライベートフィールドのデータと情報にアクセスでき(通常はバッキングフィールドから)、通常はパブリック プロパティからアクセスします(上記の例を参照)。

上記のステートメントがかなり混乱することは否定できないので、いくつかの例を見てみましょう。このコードが音楽のジャンルを参照しているとしましょう。したがって、ジャンルジャンル内では、さまざまなジャンルの音楽が必要になります。ヒップホップ、ロック、カントリーの3つのジャンルが必要だとします。これを行うには、クラスの名前を使用して、そのクラスの新しいインスタンスを作成します

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)

ジャンルクラスのインスタンスを作成したので、上記で設定した 'Name' プロパティを使用してジャンル名を設定できます。

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

次のように記述することで、「g1」の名前をHip Hopに設定できます。

g1.Name = "Hip Hop";

ここで起こっていることは、ちょっと複雑です。同様に私が前に言った、getそしてsetあなたがそうでなければアクセスすることはできないだろうと民間分野からのアクセス情報。そのプライベートフィールドから情報を読み取って返すことgetができるだけです。そのプライベートフィールドにのみ情報を書き込むことができます。しかし、両方を持つプロパティを持つことにより、そして私たちがことができるしているが、これらの機能の両方を行います。そして書くことによって、私たちはNameプロパティからの関数を具体的に使用していますsetgetsetg1.Name = "Hip Hop";set

setという暗黙の変数を使用しますvalue。基本的にこれが意味することは、内setに「値」が表示されるときはいつでも、それは変数を参照しています。「値」変数。書き込むときは、変数を渡すためにg1.Name =を使用=していvalueます"Hip Hop"。この場合はです。したがって、基本的には次のように考えることができます。

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

上記の例は実際にはコードで記述されていないことに注意することが重要です。これは、バックグラウンドで何が行われているのかを表す架空のコードです。

これで、ジャンルのg1インスタンスの名前を設定したので、次のように書くことで名前を取得できると思います

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"

これを実行すると、 "Hip Hop"と、コンソールに入ります。

この説明のために、出力も含めて例を完成させます

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

出力:

"Genres: Hip Hop, Rock, Country"

18
個人的にはコメントアウトするだけですset{name = value;} // 'value' here is equal to "Hip Hop"
maksymiuk

2
@iLoveUnicorns、それはデータ抽象化の目的のためにあります。バッキングフィールドは、実際のデータを含むものです。プロパティ定義は、getおよびsetメソッドを使用してデータにアクセスする方法を実際に定義します。私が提供したリンクには、ページ上部のJohn Guttagからの優れた引用があります。彼の本を読んだり、この無料のオンラインコースを受講
Josie Thompson

2
:のpublic class Genre{public string Name;} 代わりに:を 使用することはできません public class Genre{ public string Name { get; set; }}。つまり、なぜ{get; セットする; }?
user2048204 2016年

1
私の懸念はすでに反響しているようです。次のように宣言すると、「public string Name {get; set;}」となり、次のようにアクセスします。g1.Name= "Hip Hop"; -次に、オブジェクト指向はどこにありますか?いわゆる「バッキングフィールド」も必要ありません。私に関する限り、バッキングフィールドは存在しません。私はパブリックフィールドにのみアクセスするためです。パブリックフィールドが「パブリック」の場合、OOに準拠していません。COBOLに戻りましょう。
Baruch Atta

1
すばらしい回答ですが、私たちが知識を深めている場合、「セット」はアクセサーではなくミューテーターです。
pythlang

100

それらは自動プロパティです

基本的に、バッキングフィールドを使用してプロパティを記述する別の方法。

public class Genre
{
    private string _name;

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

7
「バッキングフィールド」とは何ですか?
kn3l 2011

4
@stackunderflow:バッキングフィールドは、データが格納される場所です。(を使用すると返され、を使用getして永続化されるものset)。食器棚のようにgetsetの扉を開きます。
グラントトーマス

5
@stackunderflow:この回答では、バッキングフィールドは_nameです。自動プロパティでは、バッキングフィールドは非表示になっています。
ジャスティン

36

これは、これを行うための短い方法です。

public class Genre
{
    private string _name;

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

33

プライベートデータメンバーを明示的に作成する必要がないように、データメンバーをパブリックとして公開するショートカットです。C#は、プライベートデータメンバーを作成します。

このショートカットを使用せずにデータメンバーをパブリックにすることもできますが、データメンバーの実装を変更してロジックを追加することにした場合は、インターフェイスを解除する必要があります。要するに、より柔軟なコードを作成するためのショートカットです。


2
ケルシー-この構文によって「柔軟な」コードになる理由を説明していただけますか?見えない。「ロジック」をセッターまたはゲッターに追加する場合、エーテルの場合(プライベートデータの有無にかかわらず)、インターフェースをそのまま壊し、コーディングが必要になります。
Baruch Atta

18

基本的には、次のショートカットです。

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
これは質問の答えにはなりません。OPはプロパティについて話していました。
theB

6
GetおよびSetプロパティを知っています。これは理解を深める一例です
Jirson Tavera


6

これらは、パブリックプロパティNameのアクセサーです。

それらを使用して、ジャンルのインスタンスでそのプロパティの値を取得/設定します。


6

これは自動実装プロパティです。基本的に、C#でクラスのプロパティを作成する簡単な方法であり、クラスのプライベート変数を定義する必要はありません。通常、変数の値を取得または設定するときに追加のロジックが必要ない場合に使用されます。

詳細については、MSDNの自動実装プロパティプログラミングガイドをご覧ください


6
  • get / setパターンは、インスタンス化されたクラスのプロパティインスタンスの設定( 'set')または取得( 'get')中にロジックを追加できる構造を提供します。これは、インスタンス化ロジックが必要な場合に役立ちます。プロパティ。

  • プロパティは 'get'アクセサーのみを持つことができます。これは、そのプロパティを読み取り専用にするために行われます

  • get / setパターンを実装する場合、中間変数は、値を配置したり値を抽出したりするためのコンテナーとして使用されます。通常、中間変数の前にはアンダースコアが付けられます。この中間変数は、get / set呼び出しを介してのみアクセスできるようにするためにプライベートです。Brandonの回答を参照してください。彼の回答は、get / setを実装するために最も一般的に使用される構文規則を示しているためです。


5

これは、ジャンルのタイプの変数を作成する場合、プロパティとして変数にアクセスできることを意味します

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

5
自動実装プロパティを使用しない場合でも、この方法でアクセスできます。つまり、AIPは外部からのアクセスではなく、クラス内での宣言です。
abatishchev

4

そのような { get; set; }構文は自動プロパティと呼ばれ、C#3.0構文

コンパイルするには、Visual C#2008 / csc v3.5以降を使用する必要があります。ただし、.NET Framework 2.0までターゲットを絞った出力をコンパイルできます(この機能をサポートするためにランタイムやクラスは必要ありません)。


4

Visual StudioではX、クラスでプロパティを定義し、このクラスをタイプとしてのみ使用する場合、プロジェクトをビルドした後、「フィールドXは割り当てられず、常にデフォルトになります」という警告が表示されます。値"

追加することにより{ get; set; }Xプロパティを、この警告は表示されません。

さらに、Visual Studio 2013以降のバージョンでは、追加する{ get; set; }ことにより、そのプロパティへのすべての参照を表示できます。

ここに画像の説明を入力してください


4

基本的には省略形です。public string Name { get; set; }多くの例のように書くことができますが、それを書くこともできます:

private string _name;

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

なぜそれが使われるのですか?プロパティへのアクセスをフィルタリングするために使用できます。たとえば、名前に数字を含めたくない場合などです。

例を挙げましょう。

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

正式には、その自動実装プロパティと呼ばれ、(プログラミングガイド)を読むのがよい習慣です。チュートリアルビデオのC#プロパティもお勧めします。「get」と「set」を使用する理由


2

取得セットは、プロパティへのアクセス修飾子です。Getはプロパティフィールドを読み取ります。Setは、プロパティ値を設定します。Getは読み取り専用アクセスのようなものです。セットは書き込み専用アクセスのようなものです。プロパティを読み書きとして使用するには、getとsetの両方を使用する必要があります。


1
get setはアクセス修飾子ではなく、実際にはアクセサーです。アクセス修飾子は次のようなものです。パブリック、プライベート、内部など
Rohit Arora 2015年

1

Getは、プロパティが右側(RHS)に表示されたときに呼び出されますSetは、プロパティが左側(LHS)に表示されたときに呼び出されます。

自動実装プロパティの場合、バッキングフィールドはシーンの背後で機能し、表示されません。

例:

public string Log { get; set; }

自動実装されていないプロパティの場合、バッキングフィールドは先行しており、プライベートスコープ変数として表示されます。

例:

private string log;

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

また、ここでは「ゲッター」と「セッター」が異なる「バッキングフィールド」を使用できることに注意してください。


これは尋ねられた質問に答えていないようです。
TylerH 2017年

get&setが呼び出されたときにヒントを提供しました。上記のすべての答えは、get&setのバッキングフィールドが同じであるという印象を与えます。しかし、そうではありません。だから私の答えはメインの質問に非常に関連しています。私に同意してください。
バラ

質問が尋ねる自動生成プロパティの場合、ゲッターとセッターに異なるバッキングフィールドを使用することはできません。バッキングフィールドは1つだけです。(質問では尋ねられない)非自動プロパティの場合、概念的にはバッキングフィールドもまったくない場合があります。さらに、割り当て演算子の左側にゲッターを使用するプログラムと、代入演算子の右側にセッターを使用するプログラムを作成できます。したがって、この情報のすべてが質問に答えていないだけでなく、それもすべて間違っています。
サービー

0

プライベート変数を定義する

コンストラクター内でデータをロードする

Constantを作成し、定数から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

プロパティは、プライベート変数をクラスの他のメンバーから分離するレイヤーのようなものです。外の世界からは、プロパティは単なるフィールドのように感じられます。プロパティには.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はプロパティです。矢印のあるものはショートカットです。外の世界から、次のようにFullNameにアクセスできます。

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

呼び出し元は、FullNameの実装方法を気にしません。ただし、クラス内では、FullNameを自由に変更できます。

詳細については、Microsoftのドキュメントをご覧ください。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.