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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Q&A

解決済

4回答

1478閲覧

プロパティ

Saya_A

総合スコア76

C#

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

0グッド

1クリップ

投稿2016/12/25 18:57

プロパティについて、setが変更用でgetが取得用と説明を見るのですが、この意味とは
あと、この時に片方だけprivaitにしている場合もあると調べるとあるのですが、これの意味が分かりません。取得したら変更しないと意味ないんじゃーとか思ってしまいます。例題levelの問題だとその部分を削っても同じ結果になってしまい違いがわからず。よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

プロパティは、まるでフィールドのようにアクセスできるだけのただの特殊なメソッドです。なにかしらのフィールドに結びつける必要も、それを取得する必要も、変更する必要もありません。引数や返り値の数や型は固定ですが、中身は自由に作成できます。

C#

1public class Hoge 2{ 3 public string Fuga 4 { 5 get { System.Console.WriteLine("get入りました!"); return ""; } 6 set { System.Console.WriteLine("set入りました!"); } 7 } 8} 9 10public class Test 11{ 12 public static void Main() 13 { 14 var hoge = new Hoge(); 15 var s = hoge.Fuga; 16 hoge.Fuga = "piyo"; 17 } 18}

ただ、これをフィールドに結びつけてフィールドの取得と変更に使うと素晴らしい威力を発揮します。フィールドに直接アクセスできても良いんじゃ無いかと思うかも知れませんが、メソッドであるという特徴とgetのみやアクセス権を調整できるという特徴から、フィールドではできないことが可能です。

  • getのみ設定することで、読み取り専用のフィールドっぽいものが作れる。
  • getやset時に追加の処理ができる。例えば、取得回数をカウントするとか、設定値が制限を満たしているかチェックするとか、連携する他のフィールドも変更するとか。
  • getとsetのアクセス権を別々にできる。取得はどこからでもできるが、変更できるのはそのクラスとそのサブクラスのみに制限などといった事ができる。

これらはいわゆるgetterやsetterのメソッドでも実現できます。しかし、通常のメソッドとの違いはフィールドのように扱えると言うことです。もし、フィールドの取得や変更をメソッドで実装しようとgetFuga()、setFuga(value)という非常にダサい呼び出し方をする必要がありますし、実装も一つ一つ行っていくのは面倒です。

また、C#では簡単に実装するための簡易な書き方が用意されています。

public class Person { public string GivenName { get; } // getのみの場合はコンストラクタでのみ設定可能 public string FamilyName { get; set; } public string FullName => FamilyName + " " + GivenName; public Person(string givenName, string familyName) { GivenName = givenName; FamilyName = familyName; } } public class Test { public static void Main() { var taro = new Person("太郎", "山田"); System.Console.WriteLine(taro.FullName); taro.FamilyName = "鈴木"; System.Console.WriteLine(taro.FullName); } }

姓は結婚や養子縁組などで変わる場合がありますが、名は特殊な場合を除き変わることはありません。このように、読み取り専用のプロパティにすることで後から変更されることが無い事を保証できます。また、フルネームのように姓と名で自動的に決まるような所はそもそもフィールドを持つ必要はありません。通常のメソッドでも同じ事はできますが、プロパティを使えば、まるでフィールドのようにアクセスできるため、呼び出し側から見るとコードがわかりやすくなります。そして、最も重要なのは、これらは本来のフィールドを完全に隠蔽していると言うことです。

つまり、何を言いたいのかというと、

Javaとは違うのだよ、Javaとは!

参考文献:
プロパティ - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
プロパティ (C# プログラミング ガイド)

投稿2016/12/25 21:11

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Saya_A

2016/12/26 02:26

かなり詳細な説明ありがとうございます! そしてJava VS C#の争いに驚愕しましたΣ(・□・;)
guest

0

setが変更用でgetが取得用と説明を見るのですが

C#

1public class C { 2 public int Value { get { ... } set { ... } } 3} 4 5C c = new C(); 6int v = c.Value; // getが動きます(Valueを参照しているから)。 7c.Value = v; // setが動きます(Valueを更新しているから)。 8c.Value++; // getが動き、その後setが動きます。

片方だけprivateにしている

以下の(あまり意味がない)例ではValueプロパティーの値が偶数かどうかを表すIsEvenプロパティーを外部に対して参照だけ許したものです。Valueが設定されたときにCクラスでIsEvenを更新しますが、Cクラス以外にもIsEvenの更新を許すとValueが奇数なのにIsEvenがtrueになるといった矛盾が起こるので参照だけ許したいわけです。

c#

1public class C { 2 public int Value { 3 get { return _Value; } 4 set { 5 _Value = value; 6 IsEven = value % 2 == 0; 7 } 8 } 9 private int _Value; 10 11 public bool IsEven { get; private set; } 12}

このようにプロパティーの値がクラス外から勝手に変更されると困るような場合に使うのが典型的な使い方だと思います。

なお反対にgetをprivateにしてsetをpublicにすることもできますがあまり見かけない気がします。

投稿2016/12/25 20:11

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

専門的な話は他の方の回答を見ていただくとして…
プログラムを書く上での取得(get)と設定(set)の挙動の基本は下記です。

  • どこからでも取得できる。
  • どこからでも変更できる。

これの問題点はグローバル変数の問題点と同じで、下記のようなことに気をつける必要が出てきます。

  • どこからでも取得できることで、意図しない取得を行う可能性がある。
  • どこからでも変更ができることで、意図しない変更が行われる可能性がある。
  • 上書きしないようにするために、同じ名前を使わないよう気をつける必要がある。

なので、プログラムのメンテナンス性(意図しない挙動をしないようにする)を高めるために、下記のように制限を課します。

  • 所定の手順を踏めば(特定のメソッドを使えば)取得・設定できる。
  • 取得はどこからでもできるが、設定は特定のクラスからしかできない。

こうすることで、意図しない取得・設定が行われることを防ぐことが出来ます(不正な取得や設定を行おうとすればエラーが出る)。

それを実現するためには、下記のような形式でコードを書く必要があります。

  • 取得する変数や値そのものの直接の参照はできない。
  • メソッドを通してのみ、取得・設定ができる。

private・publicの宣言の使い分けはそれを実現するために行います。

投稿2016/12/26 02:00

編集2016/12/26 02:04
yamato_hikawa

総合スコア2092

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

プロパティとはgetterやsetterと呼ばれるアクセサ関数を扱いやすく見やすくするために用意された機構です。
なのでプロパティの使い道や存在意義はほぼgetter,setterの話と共通しています。
そしてそれは大体オブジェクト指向の話に帰結します。

以下のURLを読むととりあえずやっておいた方がいいっていうのはわかると思います。
最初のうちはそれくらいでいいと思います。
こういうのが役に立つと実感できるのはチームである程度大きいもの作るようになってからなので。
getter, setterの必要性

投稿2016/12/26 01:44

ishi9

総合スコア1294

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問