簡體   English   中英

我正在嘗試從屬性設置器創建一個委托

[英]I am trying to make a to create a delegate from property setter

我試圖在il代碼中創建一個屬性設置器委托。 當前代碼對於字符串可以正常工作,但對於int,bool,datetime(所有值類型),我會得到“操作可能會使運行時不穩定”。

 DynamicMethod method = new DynamicMethod( "Setter", typeof ( void ), new[]
        {
            typeof ( T ), typeof ( Object )
        }, true );
        var ilgen = method.GetILGenerator();
        ilgen.Emit( OpCodes.Ldarg,0 );
        ilgen.Emit( OpCodes.Castclass, property.DeclaringType );
        ilgen.Emit( OpCodes.Ldarg,1 );
        ilgen.Emit(OpCodes.Unbox_Any, property.PropertyType);
        ilgen.Emit( OpCodes.Box,property.PropertyType );
        ilgen.Emit( OpCodes.Call, property.GetSetMethod() );
        ilgen.Emit( OpCodes.Ret );
        var action = method.CreateDelegate( typeof ( Action<T, Object> ) ) as Action<T, Object>;
        return action;


        //var target = Expression.Parameter(typeof(T), "obj");
        //var value = Expression.Parameter(typeof(Object), "value");
        //var body = Expression.Assign(
        //                             Expression.Property(Expression.Convert(target, property.DeclaringType), property),
        //                             Expression.Convert(value, property.PropertyType));

        //var lambda = Expression.Lambda<Action<T, Object>>(body, target, value);

        //return lambda.Compile();

我已經使用了unbox和box來嘗試使int工作,這兩行也可以是castclass和string可以工作,但對於值類型仍然會出現相同的錯誤。

我正在使用il代碼來嘗試避免轉換,如我的舊代碼所示。 我試圖避免轉換,因為此代碼需要盡可能快。

您知道屬性的類型,因此只需生成適當的代碼即可。 如果是引用類型,則必須強制轉換;如果是值類型,則必須取消裝箱。 這很好用:

    ilgen.Emit(OpCodes.Ldarg, 1);
    if (property.PropertyType.IsValueType)
         ilgen.Emit(OpCodes.Unbox_Any, property.PropertyType);
    else ilgen.Emit(OpCodes.Castclass, property.PropertyType);            

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM