如何在AOT平台上的运行时生成任何泛型类型?

时间:2016-05-15 12:17:41

标签: c# ios generics aot

我需要在AOT平台上的运行时生成泛型类型。我知道一个"解决方法"提示编译器通过在代码中创建一个虚方法来生成一个特定的泛型类:

public void DoDummy(){
    var a1 = new MyClass<MyType>();
}

不幸的是,这个具体的解决方法对我来说不起作用,因为我有超过几十万(没有夸张)可能创建的类型组合。

有没有办法完成我想要实现的目标?

2 个答案:

答案 0 :(得分:0)

我不是100%确定我明白你想做什么,但也许这会对你有所帮助:

private static object Create(Type genericType, params Type[] genericArguments)
{
    Type genericClass = genericType.MakeGenericType(genericArguments);
    return Activator.CreateInstance(genericClass);
}

此方法为您要创建的genericType创建所有必需的泛型类型参数,并使用其无参数构造函数创建结果类型的实例。

如果您有类似

的课程
public class MyClass<T>
{
}

并希望将string实例化为类型参数,您可以这样称呼它:

var myinstance = Create(typeof(MyClass<>), typeof(string));

请注意,如果您想有效地使用返回值(myinstance),您应该将其声明为dynamic

答案 1 :(得分:0)

虽然不是一个完美的解决方案,但我发现通过通用接口和通用抽象类可以实现比所有组合的强力列表(正常的解决方法)更好的东西。

创建一个泛型类,例如:

public abstract class GenericBase<T>
{
    public static bool AOTConstruct()
    {
        bool b = (new GV<T>() == null); // Where GV<T> is a Generic Class.
        // Do similar for all Generic Classes that need to be AOT compiled.
        return b;
    }
}

然后创建一个通用接口,例如:

public interface IGenericValue<T>
{
    GenericBase<T> ConstructGenericBase();
}

现在,可以通过声明为实现接口的类的类型,为AOTConstruct中列出的Generic类编译系统类型,如下所示:

public class SystemTypes : IGenericValue<float> // Implement IGenericValue for other Types.
{
    GenericBase<float> IGenericValue<float>.ConstructGenericBase()
    {
        throw new NotImplementedException();
    }
}

对于任何自定义类都可以这样做,可以在与系统类型相同的类中,也可以作为自定义类声明的一部分(我更倾向于清晰)。

令人失望的是必须为新的系统级类型更新SystemTypes以支持,并为需要支持的新通用类更新AOTConstruct,但它适用于编译到iOS并且不需要列出所有组合