我需要在AOT平台上运行时生成通用类型。我知道一种“解决方法”,它通过在代码中创建一个虚拟方法来提示编译器生成特定的通用类:
public void DoDummy(){
var a1 = new MyClass<MyType>();
}
很遗憾,这种特定的解决方法对我并不适用,因为我有数十万个(没有夸张)可能创建的类型组合。
是否有任何方法可以实现我所尝试达到的目标?
虽然并不是完美的解决方案,但我发现使用通用接口和通用抽象类比采用枚举所有组合(常规解决方法)要好得多。
创建一个通用类,例如:
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();
}
public class SystemTypes : IGenericValue<float> // Implement IGenericValue for other Types.
{
GenericBase<float> IGenericValue<float>.ConstructGenericBase()
{
throw new NotImplementedException();
}
}
对于任何自定义类,都可以采取同样的方法进行操作,无论是在与系统类型相同的类中,还是作为自定义类声明的一部分(我更喜欢这种方式以提高清晰度)。
不得不更新SystemTypes以支持新的系统级别类型,并更新AOTConstruct以支持需要支持的新通用类,这令人失望,但它适用于编译到iOS,并不需要列出所有组合。
我不确定我完全理解你想做什么,但也许这可以帮助你:
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
。
AOTConstruct
中列出所有打开的泛型类型,将它们从由实现接口指定的类型参数中抽象出来。由于接口现在允许默认实现(而且ConstructGenericBase
永远不会被调用),因此接口实现现在可以简化(除非我误解了什么)。您仍然需要明确列出每个泛型类型,但也许源代码生成器可以帮助解决这个问题? - monkey0506IGenericValue.ConstructGenericBase
提供默认接口实现可以简化SystemTypes
,使其仅实现接口的所有通用实现,而无需显式定义自己的ConstructGenericBase
实现。这也可能可以通过源代码生成器完成,尽管我个人不知道如何做到这一点。 - Lucas StertzConstructGenericBase
方法,而不是将其包含在接口中。然后,GenericBase<T>
可以用满足所需泛型的属性进行装饰。这将把泛型类(列在AOTConstruct
中)和它们的泛型参数(作为装饰属性的泛型参数)放在一起,以便更容易地维护。 - Lucas Stertz