ノート、反射、スレッド、プロパティ
4493 ワード
, , , 。
一つのプロジェクトをするときに、自分のプログラムをもっと柔軟にして、もっとメンテナンスしたいなら、反射は欠かせません.そこで文章では、反射を使いました.
文章全体で解決した問題は以下の通りです.
もし私がクラスを持っていたら、このクラスは他のDLLの中にいても、私の現在の工事の中で、私は動的に彼の方法を呼び出したいのですが、私はどうすればいいですか?簡単かもしれませんが、問題が少し変動したら、このクラスで呼び出したいメソッドを動的に呼び出したい場合は、どうすればいいですか?
Attributeは特性の意味で、それは私のためにこの問題を解決するために使用することができて、まず私はまずAttributeをカスタマイズして、このAttributeはネット上の資料です.
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class AttachDataAttribute : Attribute
{
public AttachDataAttribute(object key, object value)
{
this.Key = key;
this.Value = value;
}
public object Key { get; private set; }
public object Value { get; private set; }
}
ここでは、他のカスタムクラスで使用できるAttachDataというプロパティを定義します.
次はネットから写した拡張クラスです
public static class AttachDataExtensions
{
public static object GetAttachedData(
this ICustomAttributeProvider provider, object key)
{
var attributes = (AttachDataAttribute[])provider.GetCustomAttributes(
typeof(AttachDataAttribute), false);
return attributes.First(a => a.Key.Equals(key)).Value;
}
public static T GetAttachedData(
this ICustomAttributeProvider provider, object key)
{
return (T)provider.GetAttachedData(key);
}
}
このクラスは、現在の属性のAttachData特性のkeyに基づいてこのAttachData特性のvalueを取得する拡張方法をすべて持つことができるようにした.
次に拡張方法を追加しました
public static class MethodInfoExtensions
{
public static bool ContainsAttributeKey(this MethodInfo methodInfo, object AttributeKey)
{
AttachDataAttribute[] attributes = methodInfo.GetCustomAttributes(typeof(AttachDataAttribute), false) as AttachDataAttribute[];
if (attributes == null) return false;
AttachDataAttribute obj = attributes.First(a => a.Key.Equals(AttributeKey));
return obj != null;
}
}
すべてのMethodInfoオブジェクトにメソッドを持たせます.このメソッドはMethodInfoオブジェクトのプロパティにキー値があるかどうかを判断するために使用されます.もちろん、このメソッドはAttachDataプロパティを使用したメソッドにのみ適用されます.
次に、カスタムクラスを作成しました.
[AttachData(typeof(int), "t")]
public class test
{
[AttachData(typeof(int),"t")]
public string a()
{
return "a";
}
[AttachData(typeof(int), "t")]
public string b()
{
return "b";
}
}
このクラスの2つのメソッドにはAttachDataプロパティがありますが、この2つのメソッドは私が呼び出したいメソッドです.
反射を使って、testのTypeを持ってから、Typeを通じてtestのオブジェクトを持ってきました.
Type type = assembly.GetType("atest.test");
object obj = type.GetConstructor(new Type[] { }).Invoke(new object[] { });
私は方法の集合を持っていて、そして集合によって私が望んでいる2つの方法を手に入れました.
MethodInfo[] m = type.GetMethods();
List ms = m.ToList().FindAll(s => s.IsDefined(typeof(AttachDataAttribute), false));
List m1 = ms.FindAll(s => s.ContainsAttributeKey(typeof(int)));
今ではネット上で言われているinvokeを実行することができますが、私はまだ少し悪いと思います.もし私が苦労して得た2つの関数がこのようにinvokeされるしかないなら、私はこのように苦労して書く必要はありません.
2つの関数を取得しましたが、この2つの関数を使用して、各関数にスレッドを作成し、スレッドで実行したいと思います.
私はクラスを定義して、勝手に書いたのは、実験のためだけです.
class aobject
{
public MethodInfo m;
public object obj;
}
スレッドを作成しました
foreach (MethodInfo m2 in m1)
{
aobject ao = new aobject();
ao.m = m2;
ao.obj = obj;
Thread thread = new Thread(new ParameterizedThreadStart(a));
thread.Start(ao);
}
スレッドのコールバック関数は次のとおりです.
void a(object minfo)
{
aobject ao = minfo as aobject;
string re = ao.m.Invoke(ao.obj, new object[] { }).ToString();
Console.WriteLine(ao.m.Name + ":" + re);
}
私の考えは、MethodInfoをパラメータとしてスレッドコールバック関数に入力し、コールバックでwhileを使用して実行することです.信号ランプを制御すれば、成功したスレッド関数に相当します.
ここで、まとめてみましょう.私はAttachDataの特性を持っています.この特性はkeyとvalueを定義することができます.私はAttachDataExtensionsと書きましたが、文章の中で彼を使っていません.それはこの2つの拡張方法が使いやすいので、忘れてしまうのではないかと心配しています.私はここでは使えませんが.MethodInfoExtensionsを定義し、その拡張関数はmethodinfoがAttachData特性を定義し、必要なkeyが含まれているかどうかを判断します.カスタムクラスatestのTypeを反射により取得し,atestのmethodinfoの集合を取得し,この集合からAttachData特性を含み,AttachDataのkeyがType of(int)である方法を取得した.私が得た2つの方法を用いて2つのスレッドを構築した.