编写轻量ajax组件第三篇实现

2019-09-14 07:00:14王旭

  具体代码都有注释解释,最终我们获得了一个Func<object,object[],object>类型的委托,它会作为CacheMethodInfo的属性进行缓存。有兴趣测试反射性能的朋友,也不妨去测试对比一下这几种方式执行的效率差别:1.直接执行方法 2.Emit 3. 缓存+委托 4.Delegate.DynamicInvoke。

2. Executor.Execute 执行委托

  在执行委托前,我们需要先从请求获取参数,映射到方法。参数可以是简单的类型,如 string Test(int i,int j); 也可以是一个对象,如 string Test(User user); 如果是 string Test(User user1, User user2) 也行,提交参数时只需要加上 user1或 user2 前缀即可,例如 user1.Name,user2.Name。这里没有支持更多的匹配方式,像mvc,它还支持嵌套类型等等,这些可以自己去实现。如果参数是一个对象,我们可能需要为它的字段进行赋值,也可能为它的属性进行赋值。这里我们定义一个DataMember,用来表示字段或属性的父类。如:

  internal abstract class DataMember
  {
    public abstract string Name { get; }
    public abstract Type MemberType { get; }
    public abstract void SetValue(object instance,object value);
    public abstract object GetValue(object instance);
  }

  接着定义属性类型PropertyMember和字段类型FieldMember,分别继承了DataMember。

  PropertyMember定义:

  internal class PropertyMember : DataMember
  {
    private PropertyInfo property;
    public PropertyMember(PropertyInfo property)
    {
      if (property == null)
      {
        throw new ArgumentNullException("property");
      }
      this.property = property;
    }

    public override void SetValue(object instance, object value)
    {
      if (instance == null)
      {
        throw new ArgumentNullException("instance");
      }
      this.property.SetValue(instance, value, null);
    }

    public override object GetValue(object instance)
    {
      if (instance == null)
      {
        throw new ArgumentNullException("instance");
      }
      return this.property.GetValue(instance,null);
    }

    public override string Name
    {
      get { return this.property.Name; }
    }

    public override Type MemberType
    {
      get { return this.property.PropertyType; }
    }
  }

  FieldMember定义:

   

 internal class FieldMember : DataMember
  {
    private FieldInfo field;
    public FieldMember(FieldInfo field)
    {
      if (field == null)
      {
        throw new ArgumentNullException("field");
      }
      this.field = field;
    }

    public override void SetValue(object instance, object value)
    {
      if (instance == null)
      {
        throw new ArgumentNullException("instance");
      }
      this.field.SetValue(instance, value);
    }

    public override object GetValue(object instance)
    {
      if (instance == null)
      {
        throw new ArgumentNullException("instance");
      }
      return this.field.GetValue(instance);
    }

    public override string Name
    {
      get { return this.field.Name;}
    }

    public override Type MemberType
    {
      get { return this.field.FieldType; }
    }
  }