是否有可能发出一个类型从一个泛型类型

是否有可能发出一个类型从一个泛型类型

本文介绍了是否有可能发出一个类型从一个泛型类型,同时指定自己的泛型类型参数派生?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下下面的完全合法的类型层次:

Imagine the following perfectly legal type hierarchy:

class A<T> where T : A<T>
{
}

class B : A<B>
{
  public B():base(){}
}

我的问题是给A&LT的静态编译定义;?>是它可以动态地发出B型

My question is given a statically compiled definition of A<> is it possible to emit the type B dynamically?

现在的问题是如何在 ModuleBuilder.DefineType 指定父类型。

The problem is how to specify the parent type in ModuleBuilder.DefineType.

或者,也许有另一种方式来生产这种类型的,除了

Or maybe there is another way to produce such a type, other than

  • 使用上述方法
  • 使用codeDOM(这很像创建一个临时文件,将其传递给CSC.EXE: - ))

编辑:类型 B 应该有明确的公共默认构造函数调用默认的构造函数继承自 A&LT; B&GT;

The type B should have explicit public default constructor invoking the default constructor inherited from A<B>.

推荐答案

您可以使用 ModuleBuilder.DefineType 过载不指定一个父类,然后使用 TypeBuilder.SetParent 方法父设置递归式(使用参数类似于的typeof(A&LT;&GT;。)MakeGenericType(TB ),其中 TB TypeBuilder ,但我没有一个C#编译器我前面)。

You can use an overload of ModuleBuilder.DefineType which doesn't specify a parent type, and then use the TypeBuilder.SetParent method to set the parent to the recursive type (using an argument something like typeof(A<>).MakeGenericType(tb) where tb is your TypeBuilder, but I don't have a C# compiler in front of me).

修改 - 这里有一个工作的例子,假设你有一个 ModuleBuilder MB 。对于一个空的默认构造函数,你并不需要使用 DefineConstructor 办法可言;另外,您可以使用 DefineDefaultConstructor 。我已经包含其中基础构造函数显式调用,但举例来说,如果你有一些额外的逻辑,你想在里面添加。

EDIT - here's a working example, assuming you've got a ModuleBuilder mb. For an empty default constructor, you don't need to use the DefineConstructor method at all; alternatively you could use DefineDefaultConstructor. I've included an example where the base constructor is explicitly called, though, in case you have some extra logic you want to add in there.

TypeBuilder tb = mb.DefineType("B");
Type AB = typeof(A<>).MakeGenericType(tb);
tb.SetParent(AB);
ConstructorInfo ctor = TypeBuilder.GetConstructor(AB, typeof(A<>).GetConstructor(new Type[] { }));
ILGenerator ilg = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { }).GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Call, ctor);
ilg.Emit(OpCodes.Ret);
Type t = tb.CreateType();

这篇关于是否有可能发出一个类型从一个泛型类型,同时指定自己的泛型类型参数派生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 03:46