[英]Using Reflection.Emit to create a class implementing an interface
我需要使用Reflection.Emit生成一个实现以下接口的类。
public interface IObject
{
T Get<T>(string propertyName);
}
有没有人有一个例子,我将如何发出以下作为一个简单的测试用例?
class GeneratedObject : IObject
{
public T Get<T>(string propertyName)
{
// this is the simplest possible implementation
return default(T);
}
}
如果您正在使用Reflection.Emit,那么您真的应该为Reflector获取Reflection.Emit语言加载项的副本。 虽然不完美,但它应该至少可以让你获得任何给定代码的95%。
我没有方便的编译器,但这样的东西应该工作:
var aName = new AssemblyName("temp");
var appDomain = Threading.Thread.GetDomain();
var aBuilder = appDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
var mBuilder = aBuilder.DefineDynamicModule(aName.Name);
var tBuilder = mBuilder.DefineType("GeneratedObject", TypeAttributes.Public | TypeAttributes.Class);
tBuilder.AddInterfaceImplementation(typeof(IObject));
var methBuilder = tBuilder.DefineMethod("Get", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
var typeParam = mb.DefineGenericParameters(new string[] { "T" })[0];
methBuilder.SetParameters(new Type[] { typeof(string) });
methBuilder.SetReturnType(typeParam);
var ilg = methBuilder.GetILGenerator();
let lBuilder = ilg.DeclareLocal(typeParam);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, typeParam);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Ret);
var generatedType = tBuilder.CreateType();
我相信AutoMapper和/或LinFu会为你做这件事。 你绝对可以使用AutoMapper创建一个接口实例,我已经完成了。
你忘记了BOX的回报:
internal delegate object FastConstructorHandler(object[] paramters);
private static FastConstructorHandler CreateDelegate(Type Tipo)
{
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty,
typeof(object), new Type[] { typeof(object[]) }, Tipo.Module, false);
ILGenerator ilg = dynamicMethod.GetILGenerator();
ilg.DeclareLocal(Tipo);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, Tipo);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Box, Tipo);
ilg.Emit(OpCodes.Ret);
return (FastConstructorHandler)dynamicMethod.CreateDelegate(typeof(FastConstructorHandler));
}
看来,您希望通过名称快速访问对象的属性,而无需在运行时进行反射。 使用Yappi及其Property <>类,您可以实现这样的给定接口:
class GeneratedObject : IObject
{
public string Value { get { return "Test"; } }
public T Get<T>(string propertyName)
{
return Property<GeneratedObject>.Get<T>(this,propertyName);
}
}
然后像这样使用它:
IObject obj = new GeneratedObject();
var value = obj.Get<String>("Value"); //value contains "Test"
你还需要IObject和动态类型构造吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.