使用 Reflection.Emit 创建实现接口的类

发布于 2024-08-09 16:34:07 字数 382 浏览 4 评论 0原文

我需要使用 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);
    }
}

I need to generate a class using Reflection.Emit that implements the following interface.

public interface IObject
{
    T Get<T>(string propertyName); 
}

Does anyone have an example of how I would emit the following as a simple test case?

class GeneratedObject : IObject
{
    public T Get<T>(string propertyName)
    {
        // this is the simplest possible implementation
        return default(T);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

思念绕指尖 2024-08-16 16:34:07

如果您使用 Reflection.Emit,您确实应该获取 Reflection 的副本.为 Reflector 发出语言插件。虽然并不完美,但它应该能让您至少 95% 地完成任何给定的发出代码。

If you're using Reflection.Emit, you really ought to grab a copy of the Reflection.Emit language add-in for Reflector. While not perfect, it should get you at least 95% of the way to any given emitted code.

旧人九事 2024-08-16 16:34:07

我手边没有编译器,但类似这样的东西应该可以工作:

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();

I don't have a compiler handy, but something like this should work:

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();
指尖凝香 2024-08-16 16:34:07

我相信 AutoMapper 和/或 LinFu 将为您完成此操作。您绝对可以使用 AutoMapper 创建接口的实例,我已经做到了。

I believe AutoMapper and/or LinFu will do this for you. You can definitely create an instance of an interface using AutoMapper, I've done it.

慈悲佛祖 2024-08-16 16:34:07

您忘记将退货装箱:

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));
    }

You forgot to BOX the return:

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));
    }
迷途知返 2024-08-16 16:34:07

看来,您希望通过名称快速访问对象的属性,而无需在运行时进行反射。
使用 Yappi 及其属性<>类,您可以像这样实现给定的接口:

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 和动态类型构造吗?

It seems, you want to make fast access to object's properties by its name without reflection at run time.
Using Yappi and its Property<> class you can implement given interface like this:

class GeneratedObject : IObject
{
    public string Value { get { return "Test"; } }

    public T Get<T>(string propertyName)
    {
        return Property<GeneratedObject>.Get<T>(this,propertyName);
    }
}

and then use it like this:

IObject obj = new GeneratedObject();
var value = obj.Get<String>("Value"); //value contains "Test"

Do you still need IObject and dynamic type construction?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文