C# IDictionary<;obj,obj>;使用emit创建对象

C# IDictionary<;obj,obj>;使用emit创建对象,c#,dictionary,reflection.emit,C#,Dictionary,Reflection.emit,我们公司要做一些反射器 我需要一个FactoryClass,它可以通过对属性和dict键进行匹配,将IDictionary转换为obj 我发现: 这段代码可以做我想做的事情,我想使用这段代码,因为它是通过使用dotNET的basic来完成的,而不使用其他扩展 public class Populator<T> { private delegate T Load(Dictionary<string, object> properties); private

我们公司要做一些反射器

我需要一个FactoryClass,它可以通过对属性和dict键进行匹配,将IDictionary转换为obj

我发现:

这段代码可以做我想做的事情,我想使用这段代码,因为它是通过使用dotNET的basic来完成的,而不使用其他扩展

public class Populator<T>
{
    private delegate T Load(Dictionary<string, object> properties);
    private Load _handler;
    private Populator() { }
    public T Build(Dictionary<string, object> properties)
    {
        return _handler(properties);
    }
public static Populator<T> CreateBuilder(Dictionary<string, object> properties)
{
    //private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new [] { typeof(int) });
    //private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new [] { typeof(int) });
    Populator<T> dynamicBuilder = new Populator<T>();
    ...
公共类填充器
{
私有委托T加载(字典属性);
专用加载处理器;
私有填充器(){}
公共T生成(字典属性)
{
返回处理程序(属性);
}
公共静态填充器CreateBuilder(字典属性)
{
//私有静态只读方法info getValueMethod=typeof(IDataRecord).GetMethod(“get_Item”,new[]{typeof(int)});
//私有静态只读方法info isDBNullMethod=typeof(IDataRecord).GetMethod(“IsDBNull”,new[]{typeof(int)});
Populator dynamicBuilder=新的Populator();
...
当我测试这段代码时,我得到了一个错误

public ICollection<object> GetKeys(IDictionary<object, object> products)
    {
        IDictionary<object, object> product = (IDictionary<object, object>)products.ElementAt(0).Value;

        Dictionary<string, object> p = new Dictionary<string, object>();
        foreach (KeyValuePair<object, object> item in product)
        {
            p.Add(item.Key.ToString(), item.Value);
        }

        Populator<ProductTest> builder = Populator<ProductTest>.CreateBuilder(p);
        ProductTest obj = builder.Build(p); // error here


        return null;
    }
public ICollection GetKey(IDictionary产品)
{
IDictionary product=(IDictionary)products.ElementAt(0).Value;
字典p=新字典();
foreach(产品中的KeyValuePair项)
{
p、 添加(item.Key.ToString(),item.Value);
}
Populator builder=Populator.CreateBuilder(p);
ProductTest obj=builder.Build(p);//此处出错
返回null;
}
我在这里发现了错误

    public class Populator<T>
{
    private delegate T Load(Dictionary<string, object> properties);
    private Load _handler;
    private Populator() { }
    public T Build(Dictionary<string, object> properties)
    {
        return _handler(properties); // Error: JIT Compiler encountered an internal limitation.
    }
公共类填充器
{
私有委托T加载(字典属性);
专用加载处理器;
私有填充器(){}
公共T生成(字典属性)
{
return _handler(properties);//错误:JIT编译器遇到内部限制。
}
Wy的问题是为什么,以及如何解决它? stacktrace中没有额外的内容


//dennis

下面是带有一些测试代码的类,以及带有错误的映射器。 你只需要初始化klasse

// http://stackoverflow.com/questions/1273589/dynamic-object-property-populator-without-reflection

namespace Test

{

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Reflection;
using System.Reflection.Emit;


public class ProductTest
{

    public string ProductGuid { get; set; }
    public string ProductName { get; set; }

}

/// <summary>
/// Summary description for ProductMapper
/// </summary>
public class ProductMapper
{
    public ProductMapper()
    {
        DoTheMagic();
    }
    public ICollection<object> DoTheMagic()
    {
        Dictionary<string, object> product = new Dictionary<string, object>();


        product["ProductGuid"] = "Product Id";
        product["ProductName"] = "Product Name";


        Populator<ProductTest> builder = Populator<ProductTest>.CreateBuilder(product);
        ProductTest obj = builder.Build(product);


        return null;
    }
}




public class Populator<T>
{
    private delegate T Load(Dictionary<string, object> properties);
    private Load _handler;
    private Populator() { }
    public T Build(Dictionary<string, object> properties)
    {
        T obj = default(T);
        try
        {
            obj = _handler(properties); // JIT Compiler encountered an internal limitation.
        }
        catch (Exception ex)
        {
            string s = ex.Message;
        }

        return obj;
    }
    public static Populator<T> CreateBuilder(Dictionary<string, object> properties)
    {
        //private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new [] { typeof(int) });
        //private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new [] { typeof(int) });
        Populator<T> dynamicBuilder = new Populator<T>();
        DynamicMethod method = new DynamicMethod("Create", typeof(T), new[] { typeof(Dictionary<string, object>) }, typeof(T), true);
        ILGenerator generator = method.GetILGenerator();

        LocalBuilder result = generator.DeclareLocal(typeof(T));
        generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
        generator.Emit(OpCodes.Stloc, result);

        int i = 0;
        foreach (var property in properties)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(property.Key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.FlattenHierarchy | BindingFlags.Default);
            Label endIfLabel = generator.DefineLabel();

            if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
            {
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, i);
                //generator.Emit(OpCodes.Callvirt, isDBNullMethod);
                generator.Emit(OpCodes.Brtrue, endIfLabel);

                generator.Emit(OpCodes.Ldloc, result);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, i);
                //generator.Emit(OpCodes.Callvirt, getValueMethod);

                generator.Emit(OpCodes.Unbox_Any, property.Value.GetType());
                generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
                generator.MarkLabel(endIfLabel);
            }
            i++;
        }

        generator.Emit(OpCodes.Ldloc, result);
        generator.Emit(OpCodes.Ret);

        dynamicBuilder._handler = (Load)method.CreateDelegate(typeof(Load));
        return dynamicBuilder;
    }
}

}
//http://stackoverflow.com/questions/1273589/dynamic-object-property-populator-without-reflection
名称空间测试
{
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
运用系统反思;
使用System.Reflection.Emit;
公共类产品测试
{
公共字符串ProductGuid{get;set;}
公共字符串ProductName{get;set;}
}
/// 
///ProductMapper的摘要说明
/// 
公共类ProductMapper
{
公共产品映射器()
{
DoTheMagic();
}
公共ICollection DoTheMagic()
{
字典产品=新字典();
产品[“ProductGuid”]=“产品Id”;
产品[“产品名称”]=“产品名称”;
Populator builder=Populator.CreateBuilder(产品);
ProductTest obj=builder.Build(产品);
返回null;
}
}
公共类填充器
{
私有委托T加载(字典属性);
专用加载处理器;
私有填充器(){}
公共T生成(字典属性)
{
T obj=默认值(T);
尝试
{
obj=_处理程序(属性);//JIT编译器遇到内部限制。
}
捕获(例外情况除外)
{
字符串s=例如消息;
}
返回obj;
}
公共静态填充器CreateBuilder(字典属性)
{
//私有静态只读方法info getValueMethod=typeof(IDataRecord).GetMethod(“get_Item”,new[]{typeof(int)});
//私有静态只读方法info isDBNullMethod=typeof(IDataRecord).GetMethod(“IsDBNull”,new[]{typeof(int)});
Populator dynamicBuilder=新的Populator();
DynamicMethod=newdynamicmethod(“Create”,typeof(T),new[]{typeof(Dictionary)},typeof(T),true);
ILGenerator=method.GetILGenerator();
LocalBuilder结果=生成器.DeclareLocal(typeof(T));
Emit(opcode.Newobj,typeof(T).GetConstructor(Type.EmptyTypes));
生成器.Emit(操作码.Stloc,结果);
int i=0;
foreach(属性中的var属性)
{
PropertyInfo PropertyInfo=typeof(T).GetProperty(property.Key,BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.flatterhierarchy | BindingFlags.Default);
Label endIfLabel=generator.DefineLabel();
if(propertyInfo!=null&&propertyInfo.GetSetMethod()!=null)
{
生成器.Emit(操作码.Ldarg_0);
生成器.Emit(操作码.Ldc_I4,i);
//生成器.Emit(操作码.Callvirt,isDBNullMethod);
生成器.Emit(opcode.Brtrue,endIfLabel);
生成器.Emit(操作码.Ldloc,结果);
生成器.Emit(操作码.Ldarg_0);
生成器.Emit(操作码.Ldc_I4,i);
//Emit(opcode.Callvirt,getValueMethod);
Emit(opcode.Unbox_Any,property.Value.GetType());
Emit(opcode.Callvirt,propertyInfo.GetSetMethod());
生成器。标记标签(endIfLabel);
}
i++;
}
生成器.Emit(操作码.Ldloc,结果);
生成器.Emit(操作码.Ret);
dynamicBuilder.handler=(Load)method.CreateDelegate(typeof(Load));
返回dynamicBuilder;
}
}
}

希望这有帮助。

问题当然出在生成
加载
委托的代码中,但您没有发布该部分,因此我们无法真正帮助您…这是一个有趣的例外,但完全不可能用提供的代码重新编写它。非常不清楚处理程序是如何初始化的。如果您使用任何反射。发射,则您将st搞糟了IL.Hi,欢迎使用Stack Overflow,但请将其编辑到您的问题中并将其删除。因此,它并不是一个真正的讨论板,因此此答案将很快落在其他答案的下方/之间。现在看起来您