c# - 使用动态类型作为它自己的基类型的参数

标签 c# .net f# reflection.emit

我正在尝试编写一些在运行时生成类型的代码。我有一个需要实现的接口(interface),但约束给我带来了一些困难。

正如评论中所指出的那样,是的,界面看起来像无限递归,但实际上不是。它编译得很好

界面类似于:

interface IFoo<T> where T : IFoo<T>{
   T MyProperty{get;}
}

当我尝试使用 ModuleBuilder 定义我的动态类型时,我遇到了一个问题:

TypeBuilder tb = mb.DefineType(
            "typename",
             TypeAttributes.Public,typeof(object),new[]{...});

我是否可以传入一个 IFoo,其中 T 是我要定义的类型?

上面的代码在 C# 中,但在 F# 中回答,让我动态构造 class SomeType : IFoo<SomeType>也会做的很好

使用基类型而不是接口(interface)的答案也是有效的(如标题所示)。即

 TypeBuilder tb = mb.DefineType(
                "typename",
                 TypeAttributes.Public,...,null);

其中 .. 属于 SomeType<T> T 是被定义的类型

编辑: 作为用代码编写的示例,可以是:

    public interface ISelf<T> where T : ISelf<T>
    {
        T Prop { get; }
    }

    public class SelfBase<T> : ISelf<T> where T : SelfBase<T>{
        public T Prop  { get { return (T)this; } }
    }

    public class FooBar : SelfBase<FooBar>{
        public void Bar(){
            Prop.NonInterfaceMethod();
        }

        public void NonInterfaceMethod(){}
    }

那段代码确实可以编译。

最佳答案

您只需要在TypeBuilder 上使用SetParent 方法。以下是在 F# 中执行此操作的方法:

open System
open System.Reflection
open System.Reflection.Emit

type SelfBase<'t when 't :> SelfBase<'t>> =
    member x.Prop = x :?> 't

type Foo = class
    inherit SelfBase<Foo>
end

let ab = AppDomain.CurrentDomain.DefineDynamicAssembly(AssemblyName("test"), AssemblyBuilderAccess.Run)
let mb = ab.DefineDynamicModule("test")
let tb = mb.DefineType("typename", TypeAttributes.Public)
tb.SetParent(typedefof<SelfBase<Foo>>.MakeGenericType(tb))
let ty = tb.CreateType()

// show that it works:
let instance = System.Activator.CreateInstance(ty)
let prop = instance.GetType().GetProperties().[0].GetValue(instance, null)
let same = (prop = instance)

关于c# - 使用动态类型作为它自己的基类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6994919/

相关文章:

c# - Silverlight 可选字段验证

c# - 使用不同名称重写最终 (IL)/密封 (C#) 方法是否合法?

c# - 更改 NumericUpDown 的边框颜色

.net - 我如何使用 OpenCover 连接到服务?

f# - 如何将 F# 中的模块导入限制在本地范围内?

.net - 是否可以在 F# 中声明一个抽象的自动实现的属性?

c# - 将 Windows Phone 8 中 AutoCompleteBox 的 ItemSource/DataSource 设置为在 PHPMyAdmin 中创建的数据库表

c# - ASP.NET Mvc Url Action 从管理区域传递到主根

.net - 如何识别类型是否是自定义结构?

wpf - 不可变状态 - 有效地将更改传播到 GUI