开发者

using dynamic type as argument to it's own basetype

开发者 https://www.devze.com 2023-03-27 05:53 出处:网络
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.

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:

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?

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

Answer that uses a base type instead of an interface is also valid (as the title suggests). I.e.

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

where .. is of SomeType<T> and T is the type being defined

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开发者_JAVA技巧 { 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. Here's how to do it in 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)
0

精彩评论

暂无评论...
验证码 换一张
取 消