こんにちは
現在C#を勉強しているのですが、個人的にgetter, setterの必要性が無いように感じました
わざわざprivateなフィールドに外側からアクセスするためなら、getter,setterなど書かず、publicにしてしまえばいいのではないでしょうか。目的がわかりません。コードが長くなるだけではないのでしょうか。privateにする意味は外側から、アクセスされないためなのに結局アクセスする際の名前が変わっただけでアクセスできてしまう...これは意味がないんじゃ..とかんじました。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答9件
0
ちょっと調べ切れてないところがあるため、間違っているところがあるかも知れません。最初のオブジェクト指向であるSimulaについてはよくわからなかったので、割愛しています。なぜ、同じ事ができるpublicなフィールドなどと言う物があるのか?という疑問に対する読み物として読んでいただければと思います。なぜ、getterやsetterの方が良いのかは他の回答者さんの回答をお読みください。なお、この回答は純粋オブジェクト指向原理主義者の偏見に満ちています。
getterとsetterの代わりにフィールドをpublicにすればいいという考えは間違っています。そもそも、フィールドにpublicを設定できるという言語仕様そのものが間違っています。publicなフィールドがある言語は間違った実装をいつまでも採用している欠陥言語なのです。
この間違いはC++に由来します。C++はCの仕様をそのまま拡張してオブジェクト指向を実現しようとしました。正当なオブジェクト指向であるSmalltalkのようなクラスを実装することもできました。それを実現したのがObjective-Cですが、話がずれるのでそれはまた機会があれば話しましょう。では、C++の開発者はどうしたかというと構造体を拡張してクラスを作るというとんでもない手法を生み出しました。
Cの構造体は単純です。ただのデータの羅列でしかありません。そこに、メンバーとして関数を足せば、オブジェクト指向っぽい何かになることに気付きました。あとは、適当にコンストラクタとか継承とかアクセス権とか定義すれば、オブジェクト指向っぽくコーディングできるようになりました。しかし、所詮毛の生えた構造体です。メンバー変数もメンバー関数も区別することができません。なので、メンバー変数をpublicにできるのは当たり前のことでした。
C++のオブジェクト指向は成功を収めました。構造体を拡張するという発想は内部構造が単純になるため、実装も簡単でした。その流れはPythonでも採用されましたし、C++からオブジェクト指向を抜き出したJavaがその路線を踏襲することも自明のことでした。Javaはオブジェクト指向の代名詞になるぐらいに流行し、C++の間違った実装こそがオブジェクト指向だと人々は思うようになりました。
そして、C#です。C#の先祖であるObject Pascal(Delphi)もまさしくその路線でした。また、Javaへの対抗意識を燃やしていたC#がJavaと同じような構造にすることで、Java開発者を引き寄せようという戦略としても、それは当たり前のことでした。こうしてC#にも構造体を拡張したなんちゃってオブジェクト指向が実装されてしまいました。
C++ではフィールドではなくメンバー変数であり、クラスは構造体の一種であるため、publicであることは気にすることはありませんでした。黒魔術師であるC++erにとって構造体であることこそが真実であり、オブジェクト指向の機能はおまけにすぎなかったからです。この間違いにいち早く気付いたのはJavaの開発者でした。彼らはpublicなフィールドを使わずに、privateにしてgetterとsetterを実装することを推奨しました。彼らはフィールドという存在をひた隠しにするべく躍起になりましたが、自ら課した互換性という縛りのために、開発者に永遠にgetterとsetterを書き続けることを強いりました。
そんな中、ある発明がありました。まるでフィールドのようにアクセスできるメソッドにすれば違和感もなくなるということです。C#のプロパティはまさしくそれでした。あたかもフィールドのようにアクセスできるgetterとsetterを実装できました。その中身がメソッドなのかフィールドなのかは見えないようにしたのです。さらに、自動的にgetterとsetterが設定されるような構文も追加しました。JavaにはできなかったことをC#はやってのけたのです。
しかし、publicなフィールドは残されました。負の遺産は消えていなかったのです。しかし、安心してください。C#は常に進化しています。そのような負の遺産も、コード分析をすればそいつを使うのはいけないよってちゃんと指摘してくれるようになっているのです。
CA1051: 参照できるインスタンス フィールドを宣言しないでください
さすがC#です。C#さえ使っていればオブジェクト指向は完璧です。単純なgetterとsetterも簡単に実装できます。Cに毛が生えたC++や、なんちゃってオブジェクト指向のJavaとは違います。C#さえ使っていれば問題ありません。Visual StudioやMSDNが勧めてくれる推奨を疑うことはMicrosoftに対する反逆です。Windowsユーザである資格がありません。C#さえ使っていれば幸せになれるのです。
オブジェクト指向するなら、純粋オブジェクト指向であるRubyがお勧めって回答にしようとしたんだけど、C#を勧める回答になってしまった。どうしてこうなった?
投稿2016/03/18 11:42
総合スコア21749
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/18 15:45
2016/03/19 01:07
2016/03/22 09:50

0
ベストアンサー
色々メリットがありますが、
メリットの1つとして.** 値の正当性チェックを入れることができる。**などがあります。
下記のサンプルはこちらから転載しています。
C
1public class Date 2{ 3 private int month = 7; // Backing store 4 5 public int Month 6 { 7 get 8 { 9 return month; 10 } 11 set 12 { 13 // 正当性チェック:1~12以外の値は代入しない。 14 if ((value > 0) && (value < 13)) 15 { 16 month = value; 17 } 18 } 19 } 20}
投稿2016/03/18 05:14
総合スコア907
0
私がよく書くやり方ですが
C#
1public int Count { 2 get; 3 private set; 4}
これだけでも十分メリットがあると思いますよ。
投稿2016/03/19 10:58
総合スコア25
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
フィールドを private にして、単純な値の設定・取得のアクセサを public にするのがカプセル化だよ。
というのは違います。間違っています。
カプセル化という観点で見るならば、おっしゃる通りです。全然意味ないです。
オブジェクトが持つ実データを書き換えれて、実データを取得できるので、
フィールドを public にするのと違いはありません。
それ以外の観点から見た時、意味がないのか?というと、そこは人それぞれじゃないでしょうか。
僕は、set や get とタイプした時に、補完でズラっと出てきて欲しいので、
アクセサは用意しますね。
影響範囲を調査するときも、setterの呼び出し階層をたどれば、setしている場所が分かりますし。
ブレークポイントも貼れますし何かと便利ですよ。
publicフィールドにすると、set と get 両方が該当してしまい、目視による確認になりますので。
ただ、前述しましたがカプセル化という観点からだと無意味です。
そこは、そう理解したうえで書くべきだと思います。
ところで、C#にはアクセサメソッドって文化はあんまりなくないです?
プロパティとして書きますよね?
public string foo { set; get; }
みたいな。
投稿2016/03/18 04:49
編集2016/03/18 05:18総合スコア4666
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
プロパティのいいところは、インターフェースに抜き出せるところなんですよね。
以下はどちらもその応用です。
http://qiita.com/yuba/items/baceffbdbcfdc03f7945
http://qiita.com/yuba/items/dd0b4f43ae311683363e
投稿2016/03/18 06:33
総合スコア5570
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
C#でgetter/setterというのがあまりしっくりこないのですが。プロパティのことでしょうか。
私も基本はプロパティにしますが、内部実装的なところではpublicフィールドにすることもあります。
積極的に使う理由としては、デバッグのしやすさというのがありますね。get/setのところでデバッグ出力などをして実行状況をトレースしたり、ブレークポイントを置いてロジックを確認したりということができます。
投稿2016/03/18 10:00
総合スコア5944
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/18 05:01
2016/03/18 06:00

0
か、か、「考えなしに使えること自体ラピッド開発ツール(RAD)の重要な目的の1つだから」じゃないかな。
http://d.hatena.ne.jp/Kityo/20150625/1435181833
投稿2016/03/25 22:51
総合スコア12
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
たとえば以下の例だと、Kingaku の setter に 0 が渡された場合、KingakuStr は "0" になります。
Kingaku の setter が一度も呼ばれない場合は、空文字 "" です。
C#
1private int _kingaku = 0; 2private string _kingakuStr = ""; 3 4// 金額 (数値) 5public string Kingaku { 6 get { 7 return this._kingaku; 8 } 9 set { 10 this._kingaku = value; 11 this._kingakuStr = value.ToString(); 12 } 13} 14 15// 金額 (文字列) 16public string KingakuStr { 17 get { 18 return this._kingakuStr; 19 } 20}
他にも
「"1" をセットされても "01" をセットされても0埋めして "01" としてセットする」 とか、
「null の場合は "***" を返す」 とか、
プロパティ (getter/setter) にしておくと、こういうのを
呼出側のことは気にしないで
内部で勝手に書き換えられる点などが便利ですね。
一旦ただの public 変数で書いてしまうと、後から変更するのは大変ですし。
プロパティ (getter/setter) にしておけば如何様にもできます。
投稿2016/03/18 05:18
編集2016/03/18 05:20総合スコア1126
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/18 06:03

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。