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

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

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

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

Q&A

解決済

2回答

1199閲覧

属性によるメソッド呼び出し

lilac

総合スコア13

C#

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

1グッド

1クリップ

投稿2018/01/31 01:33

編集2018/01/31 02:51

前提・実現したいこと

メソッドに自作属性を付加し、そのメソッドが実行されたあと、自作属性内のメソッドが実行されるようにしたい。

発生している問題・エラーメッセージ

該当のソースコード

C#

1 2public class Hoge 3{ 4 int hogehoge = 0; 5 6 [MyAttribute] 7 public void FUGA() 8 { 9 hogehoge++; 10 } 11} 12 13 14public class MyAttribute : Attribute 15{ 16 public MyAttribute 17 { 18 } 19 20 public static void Execute() 21 { 22 //MyAttributeを付加したメソッドが終了した後 23 //当メソッドが呼び出される。 24 } 25} 26

試したこと

調査をしているなかで、「PropertyChanged.fody」で検索すると出てくる内容が近いように思いました。
これを理解して応用すれば仕組みを自作できるのではと考えておりますが見当がつかず質問させていただきました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

ozwk👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

PropertyChanged.fody のページを見てみました。

AOP(アスペクト指向プログラミング)のようです。
全てのメソッドにログ出力を差し込んだりするのに使われたりします。
残念ながら私は AOP はあまり詳しくありません。

C# AOP で検索するといくつか見つかると思います。

投稿2018/01/31 07:07

masa_n

総合スコア110

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

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

lilac

2018/01/31 07:20

AOP確認しました。 確かに実現したいことにマッチしそうです。 チャレンジしてみます。 ありがとうございました。
lilac

2018/01/31 07:36

ozwkさん 解説の分かりやすいページですね。 ありがとうございます。
guest

0

一般的にはリフレクションを使いますが、アプリケーションコードから直接 Hoge.FUGA メソッドが呼ばれたときに割り込むのではなく、コントローラーのようなラッパークラスから内部的に Hoge.FUGA メソッドを呼び出すときに割り込むようなイメージではないかと思います。

見当がつかないとのことですのでさわりだけ。
複数のクラスやメソッドを対象にするのでしたら、ジェネリックを使うとよいと思います。

1.コントローラーの初期処理で Hoge 型のメソッド情報を取得する。Type クラスの GetMethods などを参照してください。

2.メソッドに定義されている属性を取得する。

3.メソッド情報と属性情報を使って、目的のメソッドを実行してから属性に実装されている処理を実行するような Delegate を作る。

C#

1 2// コントローラーの初期処理 3// リフレクションは重いので呼び出しのたびに実行しない 4 5Type type = typeof(Hoge); 6 7MethodInfo method = type.GetMethod("FUGA" 8, BindingFlags.Instance | BindingFlags.Public 9); 10 11object[] attrs = method.GetCustomAttributes(typeof(MyAttribute), false); 12 13MyAttribute myAttr = null; 14 15if (attrs != null && attrs.Length > 0) 16{ 17 myAttr = attrs[0] as MyAttribute; 18} 19 20// 処理を実行するデリゲートを作る 21// これを保持しておく 22Action<Hoge> action = delegate(Hoge hoge) 23{ 24 method.Invoke(hoge, new object[] { }); 25 if (myAttr != null) { myAttr.Execute(); } 26}; 27 28 29// コントローラーのメソッド 30// 作成したデリゲートを実行する 31// これをアプリケーションコードから呼び出す 32public void FUGA(Hoge hoge) 33{ 34 action(hoge); 35} 36 37

投稿2018/01/31 04:32

masa_n

総合スコア110

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

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

lilac

2018/01/31 06:43 編集

ご回答ありがとうございます。 申し訳ございませんが、当内容ですと、Hogeクラスを利用する全てのコントローラーでデリゲートの実装(継承なしで考えます)が必要になりませんか? 本件、以下のような処理を呼び出し側に意識させず、呼び出されるメソッドにAttributeを付加することで解決したいのですがやはり難しいでしょうか。 public class HogeController { IHoge _hoge; IFogeFoge _fogefoge; IPiyo _piyo; public HogeController(IHoge hoge, IFogeFoge fogefoge, IPiyo piyo) { _hoge = hoge; _fogefoge = fogefoge; _piyo = piyo; } public void Fuga() { _hoge.FUGA(); MyAttribute.Execute(); //これを意識させたくない。 } public void FugaFuga() { _fogefoge.FugaFuga(); MyAttribute.Execute(); //これを意識させたくない。 } public void PiyoFuga() { _piyo.FUGA(); //IPiyoにもFUGAメソッドがあるが、 //IPiyoの実装クラスのFUGAメソッド終了後にはMyAttribute.Execute()は実行しない。 //実行する、しないを呼び出し側で意識させたくない。 } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問