- PR -

関数情報などから引数の値を取得したい

1
投稿者投稿内容
Forte
会議室デビュー日: 2007/07/24
投稿数: 19
投稿日時: 2008-04-08 12:28
ReflectionのMethodBaseクラスに、GetParametersというメソッドがありますが、
パラメータの名前や型情報は取得出来るのですが、与えられた値までは取得出来ませんでした。

Reflectionはメタデータを扱うものということで当然なのかもしれませんが、
似たような方法で、引数に与えられた値を動的に取得する方法は無いでしょうか?

ある関数が呼ばれた時、
その関数の名前や引数に与えられた値を、別の関数に渡してあげる事が目的です。

ベタで書けば渡せますが、出来ればそこを動的に…

使用環境は、
VisualStudio2005
.NetFramework2.0
VB.net
です。

よろしくお願いします。
よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2008-04-08 19:37
条件が厳しいですが、以下の条件を満たすことができるのなら、RealProxy を使って実現できます。

・対象インスタンスをインターフェイス経由で扱う、または対象インスタンスが MarshalByRefObject 派生クラスのインスタンス
・プロキシを経由させることができる (インスタンスの生成を制御できる、またはインスタンスをすり替えるができる等)

RealProxy を継承するクラスを定義することで、透過プロキシを生成することができます。
透過プロキシ経由でのメンバー呼び出し時に処理を挟むことができますので、引数を取得することができます。
以下、サンプルです。 (C# ですが)

コード:

using System;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Reflection;

namespace ConsoleApplication1
{
class Program
{
static void Main()
{
Interface1 instance = GetInstance();
instance.Method1("hoge");
Console.ReadLine();
}

static Interface1 GetInstance()
{
Class1 target = new Class1();
ArgumentCaptureProxy<Interface1> proxy = new ArgumentCaptureProxy<Interface1>(target);
Interface1 transparentProxy = (Interface1)proxy.GetTransparentProxy();
return transparentProxy;
}
}

public interface Interface1
{
void Method1(string value);
}

public class Class1 : Interface1
{
public void Method1(string value)
{
}
}

public class ArgumentCaptureProxy<T> : RealProxy
{
private T _targetInstance;

public ArgumentCaptureProxy(T targetInstance)
: base(typeof(T))
{
this._targetInstance = targetInstance;
}

public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage methodCallMessage = (IMethodCallMessage)msg;

string methodName = methodCallMessage.MethodName;
object[] args = methodCallMessage.Args;
this.Output(methodName, args);

object invokeResult = typeof(T).InvokeMember(methodName, BindingFlags.InvokeMethod, null, this._targetInstance, args);
ReturnMessage myReturnMessage = new ReturnMessage(invokeResult, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);
return myReturnMessage;
}

private void Output(string methodName, object[] args)
{
Console.WriteLine("Method Name : {0}", methodName);
Console.WriteLine("Args : ");
foreach (object arg in args)
{
Console.WriteLine(arg);
}
}
}
}



参考
http://www.ne.jp/asahi/nami/mei/cstips/adapter.html
http://blog.livedoor.jp/gushwell/archives/21880825.html

_________________
C#と諸々

[ メッセージ編集済み 編集者: よこけん 編集日時 2008-04-08 19:37 ]
kuma
大ベテラン
会議室デビュー日: 2004/02/25
投稿数: 110
投稿日時: 2008-04-08 20:04
参考:.NETでアスペクト指向プログラミング(AOP)
Forte
会議室デビュー日: 2007/07/24
投稿数: 19
投稿日時: 2008-04-09 01:30
よこけんさん
kumaさん

返答ありがとうございます!

提示して頂いたコードや参考資料は、属性やProxyクラスというモノを使うのですね。
初めて見るキーワードでした。

少し時間がかかりそうですが、熟読して理解します!
1

スキルアップ/キャリアアップ(JOB@IT)