繁体   English   中英

使用动态类型作为它自己的基本类型的参数

[英]using dynamic type as argument to it's own basetype

我正在尝试编写一些在运行时生成类型的代码。 我有一个我需要实现的接口但是约束导致了一些困难。

正如在评论中已经指出的那样,界面看起来像是无休止的递归,但事实并非如此。 它编译得很好

界面看起来类似于:

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>也会很好

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

 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM