原始的问题是:“如何修改一个用reflection得到的field值,并且保证线程安全”。根据所采用的同步技术,解决方案各有不同。如果是采用lock,那么自然可以反射得到同步对象然后使用Monitor来同步。但如果对象采用的是Interlocked那一套方法,问题就变得有些麻烦了。其中最典型的,也就是如何Increment一个reflection得到的int型field。困难之处在于Increment方法需要ref int参数(编译时),而若使用FieldInfo的GetValue方法只能得到box后的值(运行时),对其进行修改已经没有意义。既然前者的需求无法在编译时满足,那就干脆把它的编译推迟。使用Expression Tree或者类似技术可以做到。下面展示如何自增目标类Foo中具有CounterAttribute的字段。

// This attribute indicates the field to be increased.
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class CounterAttribute : Attribute
{
}public class Foo
{// This counter will be increased.[Counter]public long Counter = 0;
}class Program
{static void Main(string[] args){var foo = new Foo();// Print the counter before increasement.Console.WriteLine(foo.Counter);// Do the increasement.IncreaseCounter(foo);// Print the increased counter.Console.WriteLine(foo.Counter);}private static void IncreaseCounter(object instance){// Get the target type whose public field is to be increased.var targetType = instance.GetType();// Get the target field.var targetField = targetType.GetFields(BindingFlags.Public | BindingFlags.Instance).First(p => p.GetCustomAttributes(typeof (CounterAttribute), false).Any());// The Interlocked.Increment methodvar increaseMethod = typeof (Interlocked).GetMethod("Increment", new[] {typeof (long).MakeByRefType()});// The parameter of the finally built lambda.var parameter = Expression.Parameter(typeof (object));// Cast the parameter into the target type.var targetInstance = Expression.TypeAs(parameter, targetType);// Access the target field of the target instance, and pass it as parameter to the call of Interlocked.Increment.var call = Expression.Call(increaseMethod, Expression.Field(targetInstance, targetField));// Build the lambda.var lambda = Expression.Lambda(typeof (Action<object>), call, parameter);// Compile into delegate.var func = (Action<object>)lambda.Compile();// Call the compiled delegate.func(instance);}
}

这样做必定会有一些性能损失,但是如果lambda的Compile与调用相比少得多的话,那么影响应该不至于十分显著;更何况,原本都已经使用了反射了。

转载于:https://www.cnblogs.com/Gildor/archive/2012/01/29/2331489.html

怎样Interlocked.Increment一个反射得到的field?相关推荐

  1. Interlocked.Increment 方法 和Interlocked.Decrement 方法作用

    Interlocked.Increment 方法:让++成为原子操作:Interlocked.Decrement 方法让--成为原子操作. 什么叫原子操作呢.就是不会被别人打断,因为C#中的一个语句, ...

  2. System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)

    System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1) 在vb里面  等价于i=i-1 在C#里面 等价于i-- 是有C#自 ...

  3. ***Redis hash是一个string类型的field和value的映射表.它的添加、删除操作都是O(1)(平均)。hash特别适合用于存储对象...

    http://redis.readthedocs.org/en/latest/hash/hset.html HSET HSET key field value   (存一个对象的时候key存) 将哈希 ...

  4. JAVA反射系列之Field,java.lang.reflect.Field使用获取方法。

    2019独角兽企业重金招聘Python工程师标准>>> 首先必须明一点 Field类主要是用来辅助获取和操作类的属性的! 1.怎么通过反射获取类的属性 先来看JDK提供的方法有如下几 ...

  5. C#原子操作(Interlocked.Decrement和Interlocked.Increment)

    一.概念 在多线程环境中,不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程). 二.类 System.Threadin ...

  6. Java反射使用的Field类介绍

    一.Field类的作用 Field是一个类,位于java.lang.reflect包下.在Java反射中Field类描述的是类的属性信息,功能包括 (1)获取当前对象的成员变量的类型 (2)对成员变量 ...

  7. Java反射Method和Field简单实例

    目录 定义 使用方法 1.Field 2.Method 3.简单实例 定义 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方 ...

  8. 反射机制----Method,Field,Constructor

    public class ClassUtil {/** 打印类的信息,包括类的成员函数,成员变量*/public static void printClassMessage(Object obj){/ ...

  9. java 反射获取字段field

    为了下面测试先建对象 package com.sakyoka.test.person;import java.lang.reflect.Field;public class Person {priva ...

最新文章

  1. ADC的有效位数和信纳比计算
  2. 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
  3. 扫盲:php session缓存至memcached中的方法
  4. Dynamsoft WebAssembly条形码SDK预览
  5. 何万青 | 从天河2号到阿里云超算,P9技术大牛的职业发展智慧
  6. 一文看懂:工程项目管理软件有哪些?怎么选?
  7. 畅通工程2(prim模拟链表结构体建图+kru)
  8. 7---可变参数+Collections集合工具类+冒泡排序+Map集合
  9. 使用OpenCV测量图像中物体之间的距离
  10. 空中飞猴 题解 暴力
  11. ubuntu系统vim常用命令学习以及ubuntu软件下载安装
  12. Python变量的理解与内存管理
  13. c语言程序生活变得简单,编辑程序
  14. 宅急送 项目第七天 取派业务模块
  15. 深度学习模型训练技巧
  16. 用C++自制文字冒险选择游戏
  17. python实现阿里云物联网平台历史数据查询
  18. Win32学习笔记(五)消息
  19. c语言按专业查找学籍信息,C语言学生学籍信息管理系统设计0001
  20. Python实现自动扫雷,轻松挤上世界排行榜,破世界纪录~

热门文章

  1. 四层和七层负载均衡的区别介绍(转载)
  2. Puppet安装部署篇(一)
  3. UVALive4983 UVa1593 POJ3959 Alignment of Code【字符串流+输入输出】
  4. 定义项目名称快速启动项目
  5. Java多线程——同步问题
  6. We7 CMS 2.7beta3 版发布!SVN源码同步开放
  7. 数据库名、实例名和ORACLE_SID的区别
  8. execv shell_exec系列函数(execl,execlp,execle,execv,execvp)使用
  9. 6-7Pytorch搭建cifar10训练脚本(下)
  10. neo4j3.0 java使用_neo4j-java连接