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

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

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

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

Q&A

解決済

1回答

608閲覧

クラスの中からそのクラスのインスタンスにつけられた属性を取得する方法

NidoKota

総合スコア25

C#

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

0グッド

1クリップ

投稿2020/02/16 02:25

今、以下のようなデータの保存場所を選べるプログラムを作成しているのですが、
クラスの中からそのクラスのインスタンスにつけられた属性を知ることは可能ですか?

C#

1 2//保存場所を指定するアトリビュート 3[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] 4public class SaveAttribute : Attribute 5{ 6 public SaveAttribute (SaveType saveType) 7 { 8 this.saveType= saveType; 9 } 10 public SaveType saveType; 11} 12 13//保存場所のタイプ 14public emun SaveType 15{ 16 Txt, //txtで保存 17 Reg, //レジストリに保存 18} 19 20//値の保存場所を指定することも可能なクラス 21public class Data 22{ 23 public int Value 24 { 25 set 26 { 27 //このクラスのインスタンスにつけられたSaveAttributeから保存場所を取得し値を設定したい 28 } 29 } 30} 31

C#

1} 2//この機能を利用する側のクラス 3public class Test 4{ 5 [Save(SaveType.Txt)] 6 Data data = new Data(); 7 8 //Data data = new Data(SaveType.Txt); 9 //上の設定方法は利用者に何度もインスタンス化され保存場所を変えられる恐れがあるので都合が悪い 10} 11

現在までに、StackFrameとReflectionを利用して
Data.Valueを取得しようとした利用者のクラスの名前と、利用者クラスにあるDataのインスタンスの名前を取得することで、
FieldInfoを得てAttributeを取得するという試みを行いましたが、利用者クラスにあるDataのインスタンスの名前を取得できず、悩んでいます。

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

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

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

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

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

hihijiji

2020/02/16 05:38

Attributeはそのような使い方をするものではありません。 典型的なXY問題です。 本当の目的とそれを実現するために試みた手段を全て書いてください。
NidoKota

2020/02/16 18:23

すみません これ以上説明しようがないのでAttributeは使わずにそれぞれ別のクラスを作るようにします ありがとうございました
hihijiji

2020/02/17 02:44

方針が変わって質問自体の意味がなくなったなら、削除依頼をするか自己解決で閉じてください。
guest

回答1

0

ベストアンサー

クラスの中からそのクラスのインスタンスにつけられた属性を知ることは可能ですか?

使用される側のクラスが、使用された時に付加されたAttributeを取得するのは困難です。

ただ、質問者さんのやりたいことは別の方法で達成できると思います。
またAttribute以外の手段で目的が達成できるのであれば、多くの場合でその方が簡潔に記述できるのでおすすめです。

コンストラクタ引数

やりたいことが、インスタンス生成時に保存場所を選べるが、以降は変更できないならコンストラクタ引数を使うのが良いでしょう。

public class DataConstracter { public SaveType SaveT { get; } public DataConstracter(SaveType saveType) { this.SaveT = saveType; } }

クラス継承

やりたいことが、保存場所を選べるが、同じプロパティに違う保存場所のインスタンスを入れられないようにしたい、ならクラスを継承などで分けるのが良いでしょう。

public abstract class DataBase { public abstract SaveType SaveT { get; } } public class DataTxt : DataBase { public override SaveType SaveT => SaveType.Txt; } public class DataReg : DataBase { public override SaveType SaveT => SaveType.Reg; }

Static 変数化

かなり特殊な例ですが、こんな変わったこともできます。
やりたいことが、保存場所を選べるが、アプリケーション全体で1つの保存場所しか選べないようにしたい、ということであればStatic変数を使用します。

csharp

1public static class DataStaic 2{ 3 private static bool isInitialized = false; 4 private static SaveType saveT; 5 public static SaveType SaveT 6 { 7 get 8 { 9 //保存場所を指定する前に取得されたら、例外発生 10 if (!isInitialized) 11 throw new Exception("Not Initialized"); 12 13 return saveT; 14 } 15 } 16 17 /// <summary> 18 /// 保存場所を指定する(ただしアプリケーション全体を通して1度しか指定できない) 19 /// </summary> 20 /// <param name="saveType">保存場所</param> 21 /// <returns>設定できたか</returns> 22 public static bool InitializeSaveType(SaveType saveType) 23 { 24 if (isInitialized) 25 return false; 26 27 isInitialized = true; 28 saveT = saveType; 29 return true; 30 } 31}

投稿2020/02/17 12:59

soi013

総合スコア149

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

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

NidoKota

2020/02/17 15:00

Attributeの使い方が間違っていたんですね 複数の方法を教えていただき助かりました 今回はabstractを使った継承にします とても丁寧な回答ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問