お世話になっております.
オブジェクト指向初心者です.
プロパティについて伺いたいのですが,
疑問①
プロパティ(アクセサ?)はクラス内部の仕様を変更したときに,外部からは全く同じように使えるようにするための余裕を残す,いわばクッションのような存在
という認識はあっていますでしょうか.
疑問②
クラス内部を絶対に変更しない場合,プロパティを使わなくてもよい?
疑問③
C#の自動実装プロパティは,「クラス内部を変更する可能性はあるからクッションは敷いておきたいけど,今のところメンバ変数の値をそのままクラス利用者に使用してほしい」というときに便利
という認識の正誤
疑問④
C#の自動実装プロパティは初期値の指定が構文で可能で,これは自動実装プロパティの時のみ有効だが,今後クラス内部の構造を変更する必要がありIIのような実装をした場合,hogeを20で(宣言と同時に)初期化することはできない
→自動実装プロパティ用の初期化構文は,疑問③の場合にのみ使えて,クラス内部の仕様を変更した場合はコンストラクタ等で別個に初期化値を代入してやらねばならない?
(メンバ変数の初期値は自動生成されるコンストラクタで代入されますよね?)
C#
1//I コンパイル可能 2public int hoge{get;set;} = 10; 3 4//II エラー 5public int hoge{ 6 get {return hoge/2;} 7 set {hoge = 2*value;} 8} = 20; 9 10 11
以上四点よろしくお願いいたします.
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答5件
0
ベストアンサー
こんにちは。
順番に回答していきます。
疑問①について、
確かにプロパティは一見クッションのように見えますが、どちらかというと、外部からのアクセスをコントロールするのはinterfaceの役割ですね。
プロパティの本当の役割は、フィールド変数の「外部から(方法を問わず)アクセスできる」という「アクセスする側に主権があるデータ管理」を、プロパティの「内部から(ときには適切な加工を経て)公開する」という「オブジェクト側に主権があるデータ管理」に変更することが目的になります。
疑問②について
違います。クラス内部の変更というのは「仕様変更」のことを言っていると思いますが、疑問①の回答で書いた通り、プロパティは「データ管理」の責任の所在を明確にするためのものです。どのような状況でも基本的にプロパティを使うべきです。
疑問③について
確かに自動実装は素通しですが、ほとんどの場合setterを外部に公開することはなく、getterのみを公開することが多いです。setterを自動実装で公開する場合は、enum型など「データ型自体に制約がついているもの」を指定することが多いイメージです。
認識としては、「オブジェクトが何らかのデータを公開する」場合は全てプロパティとして公開し、フィールド変数を直接公開することはしない。そして、内部の変数をそのまま公開すればよい場合は自動実装でも問題がないだけである、と考えてしまって問題ないです。
疑問④について
自動実装の初期化構文は「getter-onlyの自動実装プロパティ」と同時に導入されたもので、威力を発揮する場面は限られます。結局のところ、インスタンス生成時にコンストラクタの先頭で代入される動作に近いもので、単に「特定の状況で楽に書ける糖衣構文」でしかないのです。
投稿2017/06/21 02:27
編集2017/06/21 02:33総合スコア4297
0
既にいろいろ回答がされていますが、自分も書いておきます。参考になれば幸いです。
疑問①
「余裕を残す、いわばクッション」という表現が自分にはピンときませんが・・・
オブジェクト指向の概念の一つ「カプセル化」を実現するため、通常クラス内の各フィールドへの直接アクセスは禁止するようにしておき、外部からはパブリックプロパティで各フィールの値を取得したり設定したりするということがもともとの目的のはずです。
「カプセル化」の結果として、質問者さんが言われる「クラス内部の仕様を変更したときに,外部からは全く同じように使えるようにする」ことが可能になるということだと思います。
疑問②
プロパティを使う目的には、開発者が意図した規則に基づいてフィールドを正しく使用できるよう保証するということもあります。それは、質問者さんが言われる「クラス内部を絶対に変更しない場合」とは関係ないですよね。
例えば、以下の記事ように、ユーザーが Visual Studio でプロパティを設定する際、範囲外であると例外をスローするようなこともできます。
Web Custom Control の例外処置
http://surferonwww.info/BlogEngine/post/2010/08/06/Exception-handling-by-web-custom-control.aspx
疑問③④
自動実装プロパティを利用する意味は、プログラミングガイドに書いてありますが、"プロパティ アクセサーに追加のロジックが必要ない場合は、プロパティをより簡潔に宣言できます" ということに尽きると思います。
例えば、最近の Entity Framework Code First でのモデルの定義に使うようなケース(下記記事参照)で有用だと思います。
新しいデータベースの Code First
https://msdn.microsoft.com/ja-jp/data/jj193542.aspx
投稿2017/06/21 03:28

退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
1 あってる。
2 間違い。「すべての」外部からクラスにアクセスするとき、プロパティを使う。
3 必ずプロパティを作らないとだめだけど、記述が長くてだるいが、自動実装を使うと記述が短くなって楽ちん
4 昔ながらのプロパティの実装をすればいい。
private int hoge = 20 public int Hoge{ get {return hoge/2;} set {hoge = 2*value;} };
プロパティを作るのに、フィールド用の変数と、get,setを書かないとだめで、変数をそのまま渡すとき、記述が長くてだるかった。
余計なことを考えずに、必ずプロパティを使う。ということだけ覚えておけばいいと思います。
必ずプロパティだけど、記述が増えるのが面倒だったので、省略記法を作ったと。
投稿2017/06/21 02:50
編集2017/06/21 02:57総合スコア1986
0
こんにちは。
まず、大きな勘違いがあると思います。プロパティはアクセサと似た機能を提供しますが、その主目的はアクセサではありません。
疑問①
プロパティがないJavaなどで使われるアクセサ(getXxx, setXxx)がこれに合致します。
しかし、元々プロパティはGUI開発ツールで例えばWidth=640;としただけでウィンドウの幅を変えることができるような機能を実装するために提案された機能です。(私の知る範囲ではVisual Basicが最初です。)
疑問②
クラス内部を変更する予定がない時、フィールドを直接公開していたと仮定します。
ある日、フィールドの仕様を変更して倍の値を保持するようにしました。
その時、フィールド名を変更し、元のフィールド名のプロパティを実装することでこの仕様変更を外部に波及させないで済むと言う使い方ができます。
他にはset/getにブレークを張ってデバッグするとか、ログを仕込む等のデバッグにも有用と思います。
疑問③
setをprivateにするなどして、リードオンリな「メンバ変数」を実装する際に便利と思います。
疑問④
ごめんなさい。その辺は把握していません。
オブジェクト指向プログラミングでは「メンバ変数」はできるだけprivateにすることが推奨されます。
そのprivateにする主旨を理解しないまま、フィールドを直接公開することは悪で関数(アクセサ)を介して公開するのは問題ないと理解している人達が少なくありませんのでご用心。
できるだけメンバ変数をprivateにした方が良い理由は「疑問①」に書かれた通りですが、オブジェクト指向プログラミング的にはメンバ変数をそのままset/getするケースは稀です。そのようなメンバ変数が多数発生する場合はクラス設計に問題が潜んでいる可能性が高いてす。
つまり、プロパティを「疑問①」の目的で使うケースもありますが、それが頻発するクラスは何か設計上の問題を抱えています。これはプロパティの主目的ではありません。単なる副産物です。
投稿2017/06/21 02:39
編集2017/06/21 03:42総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
私の考えですが、プログラムは正しく動作することが正しいので書き方はそれそぞれでよいと思います。ただ、それぞれの書き方には利点があり、それを理解して使った方が素早くより正しく動作するプログラムが書けると考えています。
C#も正しさより、良いやり方を提案しつつ、ユーザーに任せてくれるのが良い部分だと思いますので、ご自身がよいと思われる方法を選んでください。
疑問①
プロパティ(アクセサ?)はクラス内部の仕様を変更したときに,外部からは全く同じように使えるようにするための余裕を残す,いわばクッションのような存在
という認識はあっていますでしょうか.
私もクッションと考えています。
疑問②
クラス内部を絶対に変更しない場合,プロパティを使わなくてもよい?
使って問題なければ、使って問題ないでしょうね。特に、DBのレコードをデータを保持するだけのロジックのないオブジェクトであればそれで良いかもしれません。ただ、オブジェクト指向的には、内部処理との問題を気にする必要が無いようにプロパティを使うのがおススメです。(プロジェクトによって考え方があってもいいと思います。)
疑問③
C#の自動実装プロパティは,「クラス内部を変更する可能性はあるからクッションは敷いておきたいけど,今のところメンバ変数の値をそのままクラス利用者に使用してほしい」というときに便利
という認識の正誤
私はprivateのメンバ変数にもプロパティを使います。場合によっては内部の仕様変更でも、メンバ変数の出し入れの前後に処理を挟む事を思いつくこともあるからです。(それでも、ややこしいときは変数を管理するinnerClassを定義します。)
疑問④
C#の自動実装プロパティは初期値の指定が構文で可能で,これは自動実装プロパティの時のみ有効だが,今後クラス内部の構造を変更する必要がありIIのような実装をした場合,hogeを20で(宣言と同時に)初期化することはできない
確かにできたら便利そうですが、例示の書き方だと変数の名称と代入が離れていてわかりずらく見えます。また、hogeを再帰的に検索するのが正しい動きに見えます。
シンタックスシュガーを用いない方法がとりあえず良いのではないでしょうか?
投稿2017/06/21 04:10
総合スコア2884
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/21 22:56