zhuweisky

君子之行,静以修身,俭以养德。非淡泊无以明志,非宁静无以致远。

ESFramework,基于.NET的通信框架。DataRabbit,轻量的数据访问框架。sky.zhuwei@163.com
posts - 183, comments - 1219, trackbacks - 80, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

IL -- 手动处理装箱Box

Posted on 2008-05-05 15:23 zhuweisky 阅读(1627) 评论(6)  编辑 收藏 所属分类: C#专栏
    我们假设静态类DataHelper类有一个静态方法:
        public static object GetSafeDbValue(object val)
        {
            
if (val != null)
            {
                
return val;
            }

            
return DBNull.Value;
        } 
    GetSafeDbValue用于在为DbParameter赋值前,检查要赋的值是否为null,如果是,则使用DBNull.Value替换。
    ok,如果我在IL中这样来调用GetSafeDbValue:
    
        ldc.i4.s 12
        call 
object [DataRabbit]DataRabbit.DataHelper::GetSafeDbValue(object)

    则在运行时会抛出异常而导致应用程序退出,原因在于GetSafeDbValue接收的是一个引用类型的参数,而常数12是值类型的,所以必须先装箱:

        ldc.i4.s 12
        box int32
        call 
object [DataRabbit]DataRabbit.DataHelper::GetSafeDbValue(object)
    
    像上面这种情况稍加留心就可以注意到,但是在为一个object类型的属性赋值时,就不是那么明显了,这个时候仍然需要先通过box装箱值类型后,再赋值给属性,如:
//获取要赋值的IDataParameter,然后
call valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
box [mscorlib]System.DateTime
callvirt instance 
void [System.Data]System.Data.IDataParameter::set_Value(object)








    

Feedback

#1楼    回复  引用  查看    

2008-05-05 16:52 by 李战      

#2楼    回复  引用  查看    

2008-05-05 17:11 by gjcn      

李老师天天在线啊,每篇文章的沙发被你占了啊。

#3楼    回复  引用  查看    

2008-05-05 20:19 by 曲滨*銘龘鶽      
不错
我以为是如何在 C# 中坠入 il 的写法那哈哈

#4楼    回复  引用  查看    

2008-05-05 20:47 by 简爱      
DynamicMethod method = new DynamicMethod("DataRowToEntity", null, new Type[] { typeof(DataRow), typeof(T) }, typeof(T));
ILGenerator il = method.GetILGenerator();

il.DeclareLocal(typeof(DataColumnCollection));
il.DeclareLocal(typeof(DataColumn));

il.Emit(OpCodes.Ldarg_0);
EmitCall(il, typeof(DataRow).GetProperty("Table").GetGetMethod());
EmitCall(il, typeof(DataTable).GetProperty("Columns").GetGetMethod());
il.Emit(OpCodes.Stloc_0);

foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
{
Label label = il.DefineLabel();
string fieldName = field.Name.TrimStart('_');

il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldstr, fieldName);
EmitCall(il, typeof(DataColumnCollection).GetProperty("Item", new Type[] { typeof(string) }).GetGetMethod());

il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Stloc_1);

il.Emit(OpCodes.Brfalse, label);

il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_1);

EmitCall(il, typeof(DataRow).GetProperty("Item", new Type[] { typeof(DataColumn) }).GetGetMethod());
EmitCastObj(il, field.FieldType);

il.Emit(OpCodes.Stfld, field);

il.MarkLabel(label);
}

il.Emit(OpCodes.Ret);
海,哥们,不知道你对il.Emit有没有研究,你能否给我解释一下以上代码中,il.Emit()部门代码的意思,不胜感激.!

#5楼    回复  引用  查看    

2008-05-06 01:41 by 镜涛      
--引用--------------------------------------------------
李战: <img src="http://www.cnblogs.com/Emoticons/yoyocici/223852199.gif" alt="" />

--------------------------------------------------------

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
 
另存  打印