質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

  • C#

    7708questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

get setの意味

解決済

回答 6

投稿

  • 評価
  • クリップ 2
  • VIEW 2,659

dekky0910

score 61

お世話になります。
初歩的な質問なのですがよろしくお願いします。

getアクセサーsetアクセサーについてなのですが

私の解釈だと
クラス内でprivateに設定した変数を参照できるようにするためのプロパティだと思っています。

この場合、変数をpublicにした場合も同じではないのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+6

こんにちは。

変数をpublicにした場合も同じ

この点については、その通りです。
プロパティのget/setアクセサはコンパイルされるとただのメソッドとなります。C#の記述上特別な方法でアクセスできるというだけなのです。

クラス内でprivateに設定した変数を参照できるようにするためのプロパティ

この解釈については、プロパティにはその一面もありますが、それだけが全てではないです。

プロパティはその名の通り、オブジェクトを外から見た場合に、そのオブジェクトが持つ情報、状態を表現するためのものです。
その中身は変数への参照である必要もなく、自分が持つ「状態」を表すために、特定の計算を含むことも可能です。
プロパティは、基本的にはgetのみを実装するもの(オブジェクトの状態を「見せる」ためのもの)であると考えると、プロパティと変数の違いが見えてくると思います。実際の変数の中身をそのまま公開する場合もあれば、見栄え良く「加工」して見せたい場合もあるはずです。
setは変数のセットではなく、「オブジェクトの形態に外から手を加える」ものであると考えましょう。与えられたパラメータをそのまま変数にセットする必要はないのです。

よって、プロパティは単なる変数とは違い、「どのように自身の状態を公開するかを自分で決められる高機能な変数のようなもの」であると理解しておけばまずは良いでしょう。オープンソースなライブラリのソースを見てみると、プロパティがどのような概念で、どのように使われるのかが分かってくると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:19

    回答ありがとうございます。

    詳しく説明いただいて助かりました。
    しかし、アクセサーをメソッドで代用できないかという点で疑問が残ったのでオープンソースを見てみたいと思います。

    キャンセル

  • 2017/03/10 13:37 編集

    アクセサをメソッドで代用は当然できますが、それを言うなら、極端な話、オブジェクト指向の高機能な言語仕様は全てif文とgoto文で代用できると言えてしまいますよ。
    高級な言語を扱う場合はその「表現力」を最大限活用することが重要なのです。プロパティはC#の仕様の中で「オブジェクトの状態を『適切に公開する』」ことを「コードとして表現できる」ことが利点なのです。
    判断が難しい場面としては、例えば、setアクセサを使うかメソッドを使うかというのがあります。これは判断基準として「オブジェクトの『状態』を変化させる」ことを目的としているならsetter、「オブジェクト上で何らかのアクションを起こし、その結果状態が書き換わる」のであればメソッド、のような使い分けとなります。表現的に適切でなければ、「getterのみのプロパティ+状態に作用するメソッド」という組み合わせで記述することすらありえるわけです。

    キャンセル

  • 2017/03/10 14:27

    詳しく説明ありがとうございます。

    この書き込みのおかげで納得することが出来ました。
    使い分けについてもわざわざ記述していただき本当にありがとうございます!

    キャンセル

+1

それもそうですが、それよりもプロパティにアクセスしたときに実行する処理を追加できたり、別にprivate変数でなくてもその時点の値を加工して取得設定できたりといろんのが大きいと思いますが。

string hoge {
  get {
    return this.fuga + this.piyo; // fuga と piyo を連結したものを返す。
  },
  set (value){
    if(value == null) {
       // nullが代入された時、bar()を実行する
       bar();
    }
    this.fuga = null;
    this.piyo = null;
  }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:16

    回答ありがとうございます。

    値を加工して取得ということなのですが、例えば加工用のメソッドを用意しておきそこを経由して変数に値を入れたりすることも出来ると思うのですが、get setアクセサーでしか出来ない機能はあるのでしょうか?

    キャンセル

+1

オブジェクト指向における実装の隠蔽(カプセル化)に基づいたものだからじゃないでしょうか。

https://msdn.microsoft.com/ja-jp/library/ms173118.aspx

MSDNでも
「// public field (Generally not recommended.)」
と書かれている通り、publicなフィールドは非推奨ですし。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:20

    回答ありがとうございます。
    やはりpublicなフィールドは使わないほうがよいのですね・・

    キャンセル

+1

こんにちは。

setとgetの両方を実装する場合、おっしゃる通り隠蔽機能はなくなります。
getだけをpublicに実装して、外部からはRead Onlyとするような使い方もあります。
ブレークを張ることができるので、デバッグの時便利な場合もあります。

しかし、そもそもの目的はturbgraphics200さんの回答のように何か処理を仕込むことですね。
GUIフレームワークで、Widthプロバティを変更しただけで当該ウンドウの幅が変わるといった使い方が発祥だったと思います。(at Visual Basic)


ところで、プロパティの実装が「getアクセサーsetアクセサー」です。
プロパティと「getアクセサーsetアクセサー」を別物と捉えられているように読み取ったので補足しておきます。もし、私の読み取り損ないでしたらすいません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:22

    回答ありがとうございます。

    質問なのですが、getだけを実装するという部分なのですが、その場合の値の受け取り方がいまいち理解できません。
    もしよろしければご教授いただけませんでしょうか。

    キャンセル

  • 2017/03/10 13:28

    質問には C# タグがついていますよ。ご承知の通り、C# はプロパティを実装しています(PropertyDescriptor)。

    キャンセル

  • 2017/03/10 13:47

    dekky0910さん。
    プロバティの書き方は↓です。
    http://ufcpp.net/study/csharp/oo_property.html#level
    値の受け取り方は普通に代入文で受け取るだけです。

    Zuishinさん。
    「getアクセサーsetアクセサー」と「プロパティ」を別ものとして質問されている印象を受けたのですが、外したかも知れません。ご指摘ありがとうございます。回答を補正します。

    キャンセル

  • 2017/03/10 14:26

    直接変数として代入するだけでいいんですね!
    ありがとうございます。

    キャンセル

+1

クラス内でprivateに設定した変数を参照できるようにするためのプロパティだと思っています。 

それはかなり昔の話で、今は EF Code First でデーターベースを生成するときの Model での定義、

新しいデータベースの Code First
https://msdn.microsoft.com/ja-jp/data/jj193542.aspx

ASP.NET MVC などでのデータの受け渡し、データアノテーションによる検証などにも不可欠です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:25

    回答ありがとうございます。

    データベースについてはまだあまり知識が深くはないので少し勉強させていただきます。

    キャンセル

0

private なメンバ変数は(通常は)setter を経由しないと変更できないように作ります。
ということは、例えばおかしなデータ(誕生日が15月36日とか)を設定しようとしても、setter の中で処理をして弾くことができます。
もし public になっていれば、どこからでも変更できてしまい、ガードできないのです。

本質的にはメンバ変数はすべて private であり、必要に応じて getter/setter でアクセスを公開する、という考え方(get/set のメッセージを受け付ける)ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/10 13:24

    回答ありがとうございます。

    ただ値を受け取るだけではなく値の不正の確認も出来るのですね。

    疑問なのですがただ変数を入れるだけのフィールドを使用する場合でもアクセサーは実装したほうがよろしいのでしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    7708questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。