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

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

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

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

Q&A

解決済

6回答

8528閲覧

プロパティとメソッドの使い分け

haru853

総合スコア38

C#

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

1グッド

1クリップ

投稿2020/11/25 02:10

プロパティとメソッドは何を基準に使い分けるのでしょうか?
プロパティは状態、メソッドは振る舞いというのはわかるのですが
例えば人名を表す値オブジェクトがあったとします。

c#

1public sealed class PersonName : ValueObject 2{ 3 private string _firstName; 4 private string _lastName; 5 6 public PersonName(string firstName, string lastName) 7 { 8 _firstName = firstName; 9 _lastName = lastName; 10 } 11 12 ... 13}

このオブジェクトに画面表示用の値を追加する場合

C#

1public string DisplayValue => $"{_firstName} {_lastName}";

のようにプロパティにすべきか

C#

1public string ToDisplayValue() => $"{_firstName} {_lastName}";

のようにメソッドにすべきか、判断基準がよくわかりません。
デバッグ時には、値がすぐ見られるのでプロパティのほうが便利ですが、その分IDEに負荷がかかる(遅くなる)のかなと思います。
上記は簡単なケースなのでどちらでも変わらないかもしれませんが、より複雑になった場合に何を基準に使い分けをおこなうのでしょうか?

yohhoy👍を押しています

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

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

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

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

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

m.ts10806

2020/11/25 02:21

んん。 プロパティはあくまで情報を保管しておく箱であり、メソッドは一定の処理を返す道具なので、そもそも根本的に役割が違うのでは? どこからきた疑問なのでしょう
BluOxy

2020/11/25 02:57

プロパティとメソッド、それぞれが生まれた経緯を知ると良いかもしれません。
haru853

2020/11/25 02:59

箱というのはメモリ領域という解釈でよろしいでしょうか?そうしますとm.ts10806さんの場合は、上記のケースの場合、選択の余地なくメソッドを選択されるという意味でしょうか?
Zuishin

2020/11/26 00:53

私は、オブジェクトの現在の状態へのインターフェースがプロパティと解釈しています。たとえばウィンドウの大きさには、Window オブジェクトの Width や Height を使ってその状態にアクセスできます。 箱と言うと出し入れできるように想像してしまいますが、プロパティの場合は無限に出すことしかできないものもあり、また入れたものがそのまま出てくるとも限りません。不適切な代入は適切な値に変換されることもあるでしょう。 この質問の DisplayValue は _firstname や _lastname と同じくオブジェクトの持つ状態の一つでしかないのでプロパティが妥当だと思います。 ToString がプロパティではなくメソッドなのは、オブジェクトの状態ではなくオブジェクト全体を文字列に変換するという意味があるからですが、ToString で得られる文字列をそのまま返す Text プロパティが別にあっても構わないと思います。この場合、同じ結果が得られるメソッドとプロパティが同時に存在し、どちらを使っても良いことになります。プロパティにした場合、UI にバインドできる、シリアライズが簡単になるなどのメリットが生まれます。
haru853

2020/11/26 04:07

そうなんです。ToString()がメソッドなのも迷いが生まれた一因でした。 説明いただいて納得しました。ありがとうございました。
guest

回答6

0

プロパティとメソッドの使い分け

メソッドを定義すると仮定します。
そのメソッドがGet,Setから始まるような命名になる場合は冒頭のGetまたはSetを外してプロパティとして定義すべきです。


ToDisplayValue と書かれているメソッドの場合は、GetDisplayValueと読み替えられる・もしくは読み替えるべきと haru853 さんが 思う のであればプロパティであるべきです。

「いや、これはGetから始まらない(すなわちgetterではない)からメソッドであるべきなんだ」と haru853 さんが 思う のであればメソッドであるべきです。

命名基準は人の感覚・意識、会社のコーディングルール・文化などによって変わります。
ですから、あなたがどう命名すべきと思うか が使い分けの基準となります。

私は、ToDisplayValueGetFullName と命名すべきと 思う ので下記のように命名すべきと思います

c#

1public string FullName => $"{_firstName} {_lastName}";

投稿2020/11/25 03:18

BluOxy

総合スコア2663

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

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

BluOxy

2020/11/25 03:36

念のため補足にはなりますが、 > デバッグ時には、値がすぐ見られるのでプロパティのほうが便利ですが、その分IDEに負荷がかかる(遅くなる)のか > 箱というのはメモリ領域という解釈 "IDEの負荷" や "メモリの都合" は一切メソッドとプロパティの使い分けにはまったく関与しないので、その考えは基準に含めないでください。 その考えを含めるとそもそも論、「IDEに負荷がかかる・かつメモリを贅沢に使うC#は使わない。そしてIDEに負荷がかからない・かつメモリを無駄に使わない言語を使ってください」といった、質問から斜め方向の回答となってしまいます。
BluOxy

2020/11/26 10:04 編集

プロパティとメソッドの使い分けの基準は、そういった実装の都合ではなく、"コードをどのように表現するか"のような考え方の都合です。 これは言葉を話すときや文章を作るときも同じです。 今私とharu853さんは「基準」という言葉を使っています。 しかし、その言葉を「尺度」「物指し」「規準」という他の類義語に変えても同じように意味は通じます。 では、なぜ同じような意味を持つたくさんの類義語の中から私とharu853さんは「基準」という言葉を選んだのか。 それは我々の考え方の問題ではありませんか? プロパティとメソッドも同じですよ。 その処理を単なるGet/Setと見るか、それ以外と見るかで表現方は分かれるべきと思います。
haru853

2020/11/25 22:17

ありがとうございます。 > そのメソッドがGet,Setから始まるような命名になる場合は冒頭のGetまたはSetを外してプロパティとして定義すべきです。 すみません。お手数ですがもう少し教えていただけないでしょうか。 データベース・デバイス(ネットワークなどで接続されたハードウェア)からデータを取得・設定する場合(GetXxxDataやSetXxxDataなど)も同様でしょうか? (取得・設定に時間がかかる処理を含む場合も、メソッドではなくてプロパティで良いでしょうか?) > その考えを含めるとそもそも論、「IDEに負荷がかかる・かつメモリを贅沢に使うC#は使わない。そしてIDEに負荷がかからない・かつメモリを無駄に使わない言語を使ってください」といった、質問から斜め方向の回答となってしまいます。 おっしゃることもわかりますが、私はそれ以上に適材適所やバランスを重視しています。 Visual Studioの重さは感じながらも、それ以上のメリットがあるから利用していますし、普段はLINQや$"{}"などの可読性に優れた便利な方法を利用しながら、メモリ使用量や速度が重要な場面ではZStringやStringBuilderを使用したりしています。 そういった考えですので、どうしても必要ということでなければ、もう素のCやアセンブラはできれば使用したくないです。 その為、IDEへの負荷も判断基準の一因になりえるのかなと思っていました。(私の考え方が特殊なのかもしれませんね) なお私自身は、C#はメモリを無駄に使う言語とはあまり感じておらず、stackalloc・Span<T>なども用意されていて適材適所を実現できてバランスも取れていて良い言語と思って使用しています。
BluOxy

2020/11/26 02:06 編集

> 取得・設定に時間がかかる処理を含む場合も、メソッドではなくてプロパティで良いでしょうか? 疑問に思われている通り、GetやSetという単語は処理が軽そうな印象を持ちます。 なので、重い処理であることを明示したい場合はCompute,Fetch,Search,Findなどを冒頭につけます。 その場合は単純なGetter/Setterではないですからプロパティではなくメソッドとして定義するのが正当だと思います。 プロパティとメソッドの選択について、下記のような公式の記事がありました。 参考になれば幸いです。 https://docs.microsoft.com/ja-jp/previous-versions/dotnet/netframework-4.0/ms229054(v=vs.100)?redirectedfrom=MSDN > IDEへの負荷も判断基準の一因になりえるのかなと思っていました。 少し気になってプロパティとGetter/Setterメソッドの速度の差について調べてみましたが、下記に類似質問がありました。 https://stackoverflow.com/questions/12266652/performance-of-property-get-v-method 「プロパティは内部でメソッドとして実装されるため、パフォーマンスの違いはない」 「デバッガーの影響もある可能性がある。デバッガーのクラスのプロパティにカーソルを合わせると、そのプロパティが呼び出され、ツールチップを表示するためのコストがかかる可能性がある」とのことです。
BluOxy

2020/11/26 01:59

プロパティに重い処理を書くようなことがなければ、IDEへの負荷も気にする必要はないと思います。 ですから、プロパティとメソッドを使い分けについては 1. 処理内容に応じて命名をする 2. 命名がGet/Setか で判断すべきと思っています。
haru853

2020/11/26 04:09

公式ドキュメントがあったんですね。 これでだいぶ明確になりました。 丁寧に説明いただきありがとうございました。
guest

0

まあ、正直公式のリファレンスを読んで頂いた方が詳細に書かれていますが
プロパティ (C# プログラミング ガイド)

プロパティは、プライベート フィールドの値の読み取り、書き込み、または計算を行う、柔軟な機構が用意されたメンバーです。 プロパティは、パブリック データのメンバーと同様に使用できますが、実際はアクセサーという特殊なメソッドです。 メソッドの安全性と柔軟性を高めながら、簡単にデータにアクセスできます。

プロパティもまたメソッドであり、簡略な記述でクラスメンバにアクセスさせる為の手段です。
他言語にはプロパティ相当の機能がなかったりして、getter/setterメソッドで実装したりします。
提示されている例だと、プロパティで特に問題ないと思います。
取得・設定時に複雑なパラメータを必要とする場合は、通常のメソッドにせざるを得ないかもしれません。

投稿2020/11/25 02:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

haru853

2020/11/25 22:19

ありがとうございます。 radianさんもパラメータが必要かどうかで判断されているという事ですね。 参考になります。 プロパティもメソッドと考えると、BluOxyさんへのコメントに記載したとおり、時間のかかる処理を含む場合もプロパティにして良いものか、少しもやもやしてしまっています。
退会済みユーザー

退会済みユーザー

2020/11/26 02:52 編集

ネットワーク・DB等外部リソースへのアクセスがある場合、クラスメンバそのものへのデータ入出力ではないので、私なら区別するために通常のメソッドにすると思います。命名に処理内容が連想できる動詞を含めたいとか、その辺りも判断材料になるかなと思います。ただ、これは別段決まりごとがある訳ではないので、そうするべきといった類のものではないです。例えば、DateTime.Now プロパティは実際にはメンバの値を取る訳ではありません。 また、機能としてプロパティを要求されるケースもあります。例えば、WinFormsの拡張コントロールクラス作成時に、独自機能の設定をプロパティにしておくと、フォームデザイナで設定出来るようになります。
haru853

2020/11/26 04:11

参考になりました。ありがとうございました。
guest

0

ベストアンサー

上記は簡単なケースなのでどちらでも変わらないかもしれませんが、より複雑になった場合に何を基準に使い分けをおこなうのでしょうか?

プロパティの代わりにメソッドを使うというのは、プロパティが使えなかった C/C++ の名残(プログラマの頭にそれしかないとか、組織のルールがあるとか)だと思います。

オブジェクト指向の概念の一つ「カプセル化」を実現するため、通常クラス内の各フィールドへの直接アクセスは禁止するようにしておき、外部からはパブリックプロパティで各フィールドの値を取得したり設定したりするということがもともとのプロパティの目的です。

プロパティが利用できなかった C/C++ の時代はメソッドを使う他なくてそうしていたようです。下記の記事参照。

Set / Get とプロパティ
https://ufcpp.net/study/miscprog/accessor.html

他にも、プロパティを使う目的には、開発者が意図した規則に基づいてフィールドを正しく使用できるよう保証するということもあります。例えば、以下の記事ように、ユーザーが Visual Studio でプロパティを設定する際、範囲外であると例外をスローするようなこともできます。

Web Custom Control の例外処置
http://surferonwww.info/BlogEngine/post/2010/08/06/Exception-handling-by-web-custom-control.aspx

またプロパティを使う必要がある場合もあります。例えば、Entity Framework Code First でのモデルを定義を行う場合とか、ASP.NET Web Forms アプリのデータバインド式を使う場合とか。

投稿2020/11/25 02:48

編集2020/11/25 03:02
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

haru853

2020/11/25 22:05

参考URLも含めた丁寧な説明ありがとうございます。 すみません。一度ベストアンサーをつけたのですが、もう少しみなさんの意見をお聞きしたくなった為、ベストアンサーを一度はずさせてください。 後日あらためてSurferOnWwwさんにベストアンサーをつけさせていただきます。
guest

0

提示の例であれば、toStringメソッドじゃないかなあ。

クラスがPersonName:ValueObjectでなく
Personなら、既存回答の通りどちらでもいいかなあ。
readonlyのプロパティにする人は多いと想像するけど。

投稿2020/11/25 07:59

momon-ga

総合スコア4820

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

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

haru853

2020/11/25 22:20

ありがとうございます。 例が簡単すぎましたね。 個人的には、値オブジェクトの場合、ToString()はデバッグ用の値で、表示用の値は別に用意した方が間違いが起きにくいかなーと思っています。
guest

0

ご提示の例の場合、プロパティでも、メソッドでもどちらでも良いと思います。
判断基準は人によって変わると思います。
ご提示の例の場合で、自分基準で考えた場合、
今後の変更がどんなことが想定されるのかで判断すると思います。
例の名前なので、引数を追加するような変更は発生しないのではと想像し、
プロパティを使うと思います。

しかし、実は後から、引数を追加して、
別の機能を追加することが予想されるのであれば、
メソッドを使うと思います。

投稿2020/11/25 02:49

kikukiku

総合スコア514

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

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

haru853

2020/11/25 22:06

ありがとうございます。 kikukikuさんは、基本的に引数が必要になりそうかどうかで判断されているという事ですね。 参考になります。
guest

0

何を基準に使い分けをおこなうのでしょうか?

意味的にアクセサ(getter/setter)であればプロパティ,それ以外ならメソッド

という感じかな?

投稿2020/11/25 02:45

fana

総合スコア11658

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

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

haru853

2020/11/25 22:04

ありがとうございます。 fanaさんは、基本的にアクセサかどうかで判断されているという事ですね。 参考になります。
fana

2020/11/26 02:01 編集

というか,プロパティというのがそもそもそういう用途のための物だろう,と思っているので. (「プロパティであること」自体を強要(?)されている場合でもなければ)自分で書いた型にプロパティを設ける機会ってかなり少ないように思います. (単なる設定情報の塊みたいな物でもない限り,setとgetでこまごまと何かやるような物って無くないですか?)
haru853

2020/11/26 22:24

値オブジェクトなどカプセル化を進めていくとプロパティを結構使います。 シリアライザ・エンティティ・モデル・ビューモデル・ビュー間の接続(変換含む)などでも。 BluOxyさんが紹介してくださった公式ドキュメントに記載されているように、ガイドラインに違反しない場合はメソッドではなくプロパティを使用したほうが便利と感じてます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問