简体   繁体   English

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

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

I'm trying to write some code generating a type at runtime. 我正在尝试编写一些在运行时生成类型的代码。 I have an interface I need to implement but the constraint is causing me some difficulties. 我有一个我需要实现的接口但是约束导致了一些困难。

As has been noted in the comments, yes the interface looks like and endless recursion but is not. 正如在评论中已经指出的那样,界面看起来像是无休止的递归,但事实并非如此。 It compiles just fine 它编译得很好

The interface looks similar to: 界面看起来类似于:

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

When I the try to define my dynamic type using ModuleBuilder I have an issue: 当我尝试使用ModuleBuilder定义我的动态类型时,我遇到了一个问题:

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

have do I get to pass in a IFoo where T is the type I'm trying to define? 我是否可以传入IFoo,其中T是我想要定义的类型?

The code above in C# but answers in F# that let's me dynamically construct class SomeType : IFoo<SomeType> will do just fine as well 上面的代码在C#中但在F#中的答案让我动态构造class SomeType : IFoo<SomeType>也会很好

Answer that uses a base type instead of an interface is also valid (as the title suggests). 使用基类型而不是接口的答案也是有效的(如标题所示)。 Ie

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

where .. is of SomeType<T> and T is the type being defined 其中..是SomeType<T> ,T是定义的类型

EDIT: As an example of this when written in code could be: 编辑:作为一个例子,当用代码编写时可能是:

    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(){}
    }

That piece of code does indeed compile. 那条代码确实可以编译。

You just need to use the SetParent method on the TypeBuilder . 您只需要在TypeBuilder上使用SetParent方法。 Here's how to do it in F#: 以下是如何在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