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

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

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

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

2回答

6783閲覧

オブジェクト指向(C#) メンバ変数へのアクセスは,クラス内部からでもアクセサ(プロパティ?)を経由すべきか

ElecDove

総合スコア254

C#

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

2クリップ

投稿2017/06/07 02:48

お世話になっております.

オブジェクト指向プログラミング超初心者です

メンバ変数は一般にprivateにして,外部から呼び出す場合はできる限りアクセサを経由した方が保守の面や,安全の面から良いというところまでは理解しました.

ここで疑問なのですが,パフォーマンス的に問題がないとして,クラス内部からメンバ変数を操作するときもアクセサを経由した方が良いのでしょうか

getまたはsetしか持たない場合はそうもいかないでしょうが,
両方持っている場合はアクセサ経由で操作もアリなのかなと思い質問させていただきました

一般にどうするか,教えていただければと思います.

また,C#におけるプロパティは,他の言語におけるアクセサと同じ概念と考えてよいでしょうか.
アクセサはメソッドがガンガン増えていくのでプロパティでgetとsetを一つにまとめた?ような

よろしくお願いいたします

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

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

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

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

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

guest

回答2

0

BAがついていますので解決したと思いますが、敢えて回答してみます。

C#の言語仕様上

C#

1class Class1 2{ 3 private string _prop1; 4 5 public string Prop1 { 6 get { return _prop1; } 7 protected set { _prop1 = value ?? string.Empty; } 8 } 9 public int Prop2 { get; private set; }; 10 11 public Class1() 12 { 13 this.Prop1 = System.IO.Path.Combine(System.Environment.CurrentDirectory, "testdir"); 14 this.Prop2 = 64; 15 } 16}

のように、setter をアクセス制限する記述ができます。これは明確にクラス内部または派生クラスから「プロパティ」(アクセサ経由)で操作することを意図しています。

ただ、.NET Framework のソースコード(http://referencesource.microsoft.com/ MSさんのコーディング)を覗いてみると、コンストラクタでプロパティを初期化(代入)している操作が大半のようでした。

C#

1// 一例 "System.OperationCanceledException" 2namespace System { 3 4 [Serializable] 5 [System.Runtime.InteropServices.ComVisible(true)] 6 public class OperationCanceledException : SystemException 7 { 8 [NonSerialized] 9 private CancellationToken _cancellationToken; 10 11 public CancellationToken CancellationToken 12 { 13 get { return _cancellationToken;} 14 private set { _cancellationToken = value;} 15 } 16 17// 略 18 19 public OperationCanceledException(CancellationToken token) 20 :this() 21 { 22 CancellationToken = token; 23 } 24 25 public OperationCanceledException(String message, CancellationToken token) 26 : this(message) 27 { 28 CancellationToken = token; 29 } 30 31 public OperationCanceledException(String message, Exception innerException, CancellationToken token) 32 : this(message, innerException) 33 { 34 CancellationToken = token; 35 } 36 37 protected OperationCanceledException(SerializationInfo info, StreamingContext context) : base (info, context) { 38 } 39 } 40} 41

monon-ga さんのご回答どおり、プロパティとメンバ変数(フィールド)の区別がつきにくい限りは、メンバ変数を直接参照するか分かり易いメソッドで取り扱うことにしてアクセサを経由させないほうが、相互参照による無限ループや、見えにくい副作用の類を防げると思います。
ただ「自動実装プロパティ」(最初のコードのProp2のような記述)を使用する限り、プロパティ参照をせざるをえませんが...(自動実装プロパティをアクセサとみるかメンバ変数(フィールド)とみるかによりますが)

投稿2017/06/07 04:02

編集2017/06/07 04:05
hsk

総合スコア728

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

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

ElecDove

2019/10/12 05:30

お礼が遅くなり申し訳ありません. >これは明確にクラス内部または派生クラスから「プロパティ」(アクセサ経由)で操作することを意図しています。 >ただ、.NET Framework のソースコード~~している操作が大半のようでした。 内部からのアクセスを想定したprivate set構文だが,実際にMSが使っているのはコンストラクタでの初期化が大半だった,という解釈であっていますでしょうか. 実装の意図と実運用が若干離れているのですね >アクセサを経由させないほうが 二年も前で恐縮ですが,そのように統一しています
guest

0

ベストアンサー

内部の状態を壊さないという前提なら、アクセサ使わない方がよいです。

まぁ、パフォーマンス気にしない単純なものなら、アクセサ経由しても・・・
となって、使ったり使わなかったりが混ざったり、パフォーマンスを気にする基準って?
とか考えると面倒なので・・・

内部は一律アクセサを使わない

のルールがシンプルだと思います。

まぁ極論として、setXXの中でsetXXを再帰的に呼ぶなんて実装は、そもそもやらないでしょ?(w

投稿2017/06/07 03:02

momon-ga

総合スコア4820

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

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

ElecDove

2017/06/07 03:04

回答ありがとうございます >内部は一律アクセサを使わない >のルールがシンプルだと思います。 そうしたいと思います 助言ありがとうございました >setXXの中でsetXXを再帰的に呼ぶなんて実装は、そもそもやらないでしょ?(w 確かにそういわれてみればそうですねw
Zuishin

2019/10/12 05:45

私は逆にアクセサを使う派です。でないと後で副作用をつけた時にコード中をひっかき回さなくてはならなくなります。IDE を使えば参照されているところを教えてくれるので、気づきさえすれば大した手間でもありませんが、他から参照されていることに気づかず副作用を実装した時にバグの原因になります。逆にフィールドを直接読み書きするのは「副作用を無視する」という意志を明示するときと決めています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問