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

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

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

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

オブジェクト指向

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

Q&A

解決済

3回答

6362閲覧

C# 変数の他クラスからの設定

khr0404

総合スコア43

C#

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

オブジェクト指向

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

0グッド

0クリップ

投稿2016/12/05 02:12

編集2016/12/05 02:45

###前提・実現したいこと
閲覧頂有難うございます。

現在C#でコーディングをしているのですが、boolの値を別クラスから設定したいのですが、thisを含んでおり、
他のクラスでFlgを設定する際
静的プロパティ、静的メソッド、静的フィールド初期化子では無効です。
というエラーがでてしまいます。

オブジェクト指向がまだ理解できていない部分もあるのですが、このFlgを他クラスから値を設定するにはどのようにしたらよいでしょうか?

###該当のソースコード

C#

1 /// <summary>フラグ</summary> 2 /// <remarks></remarks> 3 private bool? _Flg = null; 4 5 /// <summary>>フラグのプロパティ</summary> 6 /// <remarks></remarks> 7 public bool? Flg 8 { 9 set { this._Flg = value; } 10 get { return this._Flg; }

デフォルト表示のカラム設定を行うクラスでこのフラグをtrueに固定しなくてはいけないため、他クラスからあるペー儀からのみfalseにしなければなりません。
固定してあるソースは

this._Flg = true;
if (this._Flg.HasValue) this._SearchReg.Flg = this._Flg.Value;
if文は他の動作をした時に値を返す用です。

###試したこと
他クラスで
this._Flg = false;

とするとthisを含んでいるのでエラーとなります。

###補足情報(言語/FW/ツール等のバージョンなど)
visualsutudio2008

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

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

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

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

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

ozwk

2016/12/05 03:10 編集

他クラス側もとりあえず、どういうクラス宣言の中のどういうメソッドの中でどう処理しているかコード書いてもらえますか?
guest

回答3

0

こんにちは。

その「他のクラス」で、Flgを含むクラスのインスタンスを持っていると思います。
そのインスタンス.Flg=false;でできますよ。

逆に、Flgを含むクラスのインスタンスを持ってないなら設定できません。その場合は設計が不適切です。
もう少し広い範囲の情報が必要です。ozwkさんが依頼されているような情報です。

投稿2016/12/05 04:33

Chironian

総合スコア23272

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

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

0

ベストアンサー

khr0404さんが提示しているクラスのthisと他のクラスで呼び出したthisの中身は別のものです。
thisは定義されたクラスのインスタンス自身を示します。インスタンスが何かわからなければ、詳細は自分でも調べて欲しいのですが、あるクラスという属性を持つ個体だと思ってください。

例えばPerson(人間)というクラスにはAさん、Bさんなどの個体がいると思いますが、thisはインスタンスがAさんだとすると、this.ageは、Aさん.ageに処理が置き替わり、インスタンスがBさんだとすると、Bさん.ageに置き替わり、それぞれのageの値にアクセスできるなどというような感じで使います。
つまり、thisはインスタンス自身を示し、それぞれAさん.age,Bさん.ageなどを別々の変数に定義する必要がないということです。分かりやすいメソッドを定義すると、Aさん.age=20;,Bさん.age=21;とした時に、

C#

1void AddAge(){ 2 this.age++; 3}

というインスタンスメソッドをそれぞれ、Aさん.AddAge(),Bさん.AddAge()の実行後、前者はAさんがメソッドを呼び出したので、Aさん.ageは21,後者はBさんがメソッドを呼び出したので、Bさん.ageは22になります。thisはそのメソッドを呼び出したインスタンス自身を指していることをわかって頂けたでしょうか。

次に、違うクラスで、this._Flgはなぜエラーが出るかというと、thisはそのクラスのインスタンスなので、当然違うクラスに書かれたthisは違うクラスのインスタンスのみに適用されます。このインスタンスのクラスには、_Flgというパラメータが存在しないので、エラーがでます。また仮に_Flgが定義されていたとしても、他のクラスが指し示すパラメータとは異なるパラメータなので、this._Flgは自身の所属するクラスのインスタンスのパラメータアクセスになり、他のクラスのインスタンスのパラメータアクセスはできません。ではどうすれば良いかというと、直接そのインスタンスを取得して、プロパティ経由で._Flgの値を書き換えれば良いのです。

提示しているクラスを他のクラスで操作したければ、他のクラスの中で操作対象のクラスのオブジェクトのインスタンスをnewで作成して直接操作するか、他クラスに操作したいクラスの変数を引数に取る関数を作って、その中で、FLGプロパティ経由で_FLGを変更してあげれば大丈夫です。具体的には、

C#

1void ChangeFlag(TargetClass target){ 2 target.Flg = !target.Flg; 3} 4 5あるいは、 6 7var target = new TargetClass(); 8target.Flg = true (or false); 9 10など

などとします。なぜ._Flgを直接書き換えないかというと、privateを元のクラスで指定しているので、他クラスからこの変数にアクセスできないからです。代わりに提示していただいているコードには、Flgのgetterとsetterというアクセサと呼ばれる特殊なメソッドを定義していて、instance.Flg=(適当な値);とすると、instance._Flgが書き換わり、var 適当な変数名=instance.Flg;とすると、instance._Flgの値が取得できるように定義していて、これがpublicなので他のクラスから呼び出せるようにしています。

なぜこのように、メソッド経由で値を書き換えるという回りくどいことをするかというと、仮に._Flgの名前を変えたくなったり,._Flag自体を何らかのクラスのパラメータの一部に変更したくなった時に、._Flgを直接変更すると、._Flgを呼び出しているコードすべてに書き換えコストが生じてしまいます。アクセサを定義しておくと、今回の例では、._Flgの名前や構造が変わっても、Flgメソッドの中身をそこから整合性のあるデータに変えるだけで、.Flgを呼び出している場所は何も変更しなくてもコードが動くことを保証できるようになります。

大体ここに書かれている内容がわかるようになれば、オブジェクト指向に慣れると思うので頑張ってください。

補足

C#

1void ChangeFlag(TargetClass target){ 2 target.Flg = !target.Flg; 3}

実際は、このメソッドは、他クラスに全く依存しない処理ので,元のクラスにインスタンスメソッドとして実装するか、staticメソッドにするのが良いです。(スタンダードなオブジェクト指向に則るなら前者がいいと思います)

C#

1Class TargetClass{ 2 void ChangeFlag(){ 3 this.Flg = !this.Flg; 4 } 5} 6他クラスのどこかで 7(ターゲットクラスのinstance).ChangeFlag()を呼ぶ

という感じです。

投稿2016/12/05 05:03

編集2016/12/05 05:18
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

データにアクセスできるのは、PublicなPropertyになりますので、今回だと、Flgにアクセスをしましょう。
基本的なサンプルだと、

csharp

1public class DemoModel 2{ 3 private bool? _isRed = null; 4 //単純なプロパティ 5 public bool? IsRed 6 { 7 get { return _isRed; } 8 set { _isRed = value; } 9 } 10 11 12 private bool? _isBlue = null; 13 //set時に何かしたいときの例 14 public bool? IsBlue 15 { 16 get { return _isBlue; } 17 set 18 { 19 _isBlue = value; 20 if (value == true) _isRed = false; 21 } 22 } 23}

という入れ物があるとすれば、

csharp

1//入れ物をインスタンス化して、とりあえず値を入れてみます。 2var model = new DemoModel() 3{ 4 IsBlue = false, 5 IsRed = true 6}; 7 8//値の更新 9model.IsBlue = true; 10model.IsRed = false;

という感じで書いておけば伝わりますでしょうか。set時に他のことをしたければ、IsBlueのsetterのようにすればいいですし、getterで何かしたければ、getterの中で追加してコードを書けばよいです。

なお、余談ですが、
INotifyPropertyChangedインターフェースやRXでのやり方もありますが...興味がありましたら調べてみるとよりC#を楽しめるかもしれません。
また、好みやコーディング規約とかにもよるとは思いますが、boolの変数名には、例に書かせて頂いたような感じの方がリーダブルです。IsRedという変数名であれば、赤だったらtrueになるとか、CanExecuteというプロパティ名であれば、実行できるときはtrue、実行できなければfalseになるのが伝わります。
(完全に余談でしたね....)

投稿2016/12/05 05:01

BEACHSIDE

総合スコア294

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問