笔记,反射、线程、特性

文章中有一部分来自网上找的资料,这部分资料很重要,为了不忘却,笔记。

 


如果在做一个项目的时候,想让自己的程序更加灵活,更加好维护,那么反射是少不了的。因此文章中,我使用了反射。

整个文章解决的问题如下:

如果我有一个类,这个类不管是在别的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<T>(
            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对象的特性中是否有某个key值,当然这个方法只能适用于使用了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";
        }
    }


 

这个类中的两个方法都有AttachData特性,而这两个方法也就是我想要调用的方法。

使用反射,当我拥有了test的Type之后,通过Type我有了test的一个对象

Type type = assembly.GetType("atest.test");
object obj = type.GetConstructor(new Type[] { }).Invoke(new object[] { });


我有了方法的集合,并且根据集合我获得了我想要的这两个方法

MethodInfo[] m = type.GetMethods();
List<MethodInfo> ms = m.ToList().FindAll(s => s.IsDefined(typeof(AttachDataAttribute), false));
List<MethodInfo> m1 = ms.FindAll(s => s.ContainsAttributeKey(typeof(int)));


 

现在就可以执行网上都在说的invoke了,但是我觉得还差了点东西,如果我千辛万苦获得的两个函数就只能如此被invoke了,那我何必这样辛苦绕着写?

我获得了两个函数,但是我想用这两个函数,每个函数建立一个线程,在线程中来执行。


我定义了一个类,随便写的,只是为了实验

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,但是文章中并未使用到他,那是因为这两个个扩展方法很好用,怕忘记了,虽然我这里用不到。
我定义了MethodInfoExtensions,它的扩展函数可以判断某个methodinfo是否被定义了AttachData特性,并且是否含有我需要的某个key。
我通过反射获取了自定义类atest的Type,并且获取了atest的methodinfo的集合,并且从这个集合中获取了含有AttachData特性,并且AttachData的key为Typeof(int)的方法。
我使用我获得的两个方法建立了两个线程。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值